diff --git a/README.md b/README.md index 86dbe223..6013a304 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Hosting for Moonlight's Debian and L4T package repositories is graciously provid ### Linux/Unix Build Requirements * Qt 6 is recommended, but Qt 5.9 or later is also supported (replace `qmake6` with `qmake` when using Qt 5). * GCC or Clang -* FFmpeg 5.0 or later +* FFmpeg 4.0 or later * Install the required packages: * Debian/Ubuntu: * Base Requirements: `libegl1-mesa-dev libgl1-mesa-dev libopus-dev libsdl2-dev libsdl2-ttf-dev libssl-dev libavcodec-dev libavformat-dev libswscale-dev libva-dev libvdpau-dev libxkbcommon-dev wayland-protocols libdrm-dev` diff --git a/app/streaming/video/ffmpeg-renderers/drm.cpp b/app/streaming/video/ffmpeg-renderers/drm.cpp index 448afef9..b539c192 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.cpp +++ b/app/streaming/video/ffmpeg-renderers/drm.cpp @@ -93,8 +93,10 @@ static const std::map k_DrmToAvFormatMap {DRM_FORMAT_NV21, AV_PIX_FMT_NV21}, {DRM_FORMAT_P010, AV_PIX_FMT_P010LE}, {DRM_FORMAT_YUV420, AV_PIX_FMT_YUV420P}, +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 27, 100) {DRM_FORMAT_NV24, AV_PIX_FMT_NV24}, {DRM_FORMAT_NV42, AV_PIX_FMT_NV42}, +#endif {DRM_FORMAT_YUV444, AV_PIX_FMT_YUV444P}, {DRM_FORMAT_Q410, AV_PIX_FMT_YUV444P10LE}, #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 34, 100) @@ -111,7 +113,9 @@ static const std::map k_DrmToAvFormatMap {DRM_FORMAT_NA12, AV_PIX_FMT_P010LE}, {DRM_FORMAT_NV15, AV_PIX_FMT_P010LE}, {DRM_FORMAT_P030, AV_PIX_FMT_P010LE}, +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 9, 100) {DRM_FORMAT_NV30, AV_PIX_FMT_P410LE}, +#endif }; // This map is used to determine the required DRM format for dumb buffer upload. @@ -124,8 +128,10 @@ static const std::map k_AvToDrmFormatMap {AV_PIX_FMT_P010LE, DRM_FORMAT_P010}, {AV_PIX_FMT_YUV420P, DRM_FORMAT_YUV420}, {AV_PIX_FMT_YUVJ420P, DRM_FORMAT_YUV420}, +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 27, 100) {AV_PIX_FMT_NV24, DRM_FORMAT_NV24}, {AV_PIX_FMT_NV42, DRM_FORMAT_NV42}, +#endif {AV_PIX_FMT_YUV444P, DRM_FORMAT_YUV444}, {AV_PIX_FMT_YUVJ444P, DRM_FORMAT_YUV444}, {AV_PIX_FMT_YUV444P10LE, DRM_FORMAT_Q410}, diff --git a/app/streaming/video/ffmpeg-renderers/sdlvid.cpp b/app/streaming/video/ffmpeg-renderers/sdlvid.cpp index b520502f..1467ce52 100644 --- a/app/streaming/video/ffmpeg-renderers/sdlvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/sdlvid.cpp @@ -343,6 +343,8 @@ ReadbackRetry: m_RgbFrame->format = AV_PIX_FMT_BGR0; sws_freeContext(m_SwsContext); + +#if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(6, 1, 100) m_SwsContext = sws_alloc_context(); if (!m_SwsContext) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, @@ -377,6 +379,19 @@ ReadbackRetry: av_make_error_string(string, sizeof(string), err)); goto Exit; } +#else + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, + "CPU color conversion is slow on FFmpeg 4.x. Update FFmpeg for better performance."); + + m_SwsContext = sws_getContext(frame->width, frame->height, (AVPixelFormat)frame->format, + m_RgbFrame->width, m_RgbFrame->height, (AVPixelFormat)m_RgbFrame->format, + 0, nullptr, nullptr, nullptr); + if (!m_SwsContext) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "sws_getContext() failed"); + goto Exit; + } +#endif } else { // SDL will perform YUV conversion on the GPU @@ -526,10 +541,18 @@ ReadbackRetry: m_RgbFrame->data[0] = pixels; m_RgbFrame->linesize[0] = texturePitch; +#if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(6, 1, 100) // Perform multi-threaded color conversion into the locked texture buffer err = sws_scale_frame(m_SwsContext, m_RgbFrame, frame); +#else + // Perform a single-threaded color conversion using the legacy swscale API + err = sws_scale(m_SwsContext, frame->data, frame->linesize, 0, frame->height, + m_RgbFrame->data, m_RgbFrame->linesize); +#endif + av_buffer_unref(&m_RgbFrame->buf[0]); SDL_UnlockTexture(m_Texture); + if (err < 0) { char string[AV_ERROR_MAX_STRING_SIZE]; SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,