mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-11-13 23:17:09 +00:00
Use SDL to render on Wayland for VAAPI
This commit is contained in:
parent
ada2270bd1
commit
b8b633a6cc
4 changed files with 30 additions and 29 deletions
|
@ -41,6 +41,11 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool isDirectRenderingSupported() {
|
||||||
|
// The renderer can render directly to the display
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// IOverlayRenderer
|
// IOverlayRenderer
|
||||||
virtual void notifyOverlayUpdated(Overlay::OverlayType) override {
|
virtual void notifyOverlayUpdated(Overlay::OverlayType) override {
|
||||||
// Nothing
|
// Nothing
|
||||||
|
|
|
@ -76,8 +76,6 @@ VAAPIRenderer::initialize(PDECODER_PARAMETERS params)
|
||||||
}
|
}
|
||||||
else if (info.subsystem == SDL_SYSWM_WAYLAND) {
|
else if (info.subsystem == SDL_SYSWM_WAYLAND) {
|
||||||
#ifdef HAVE_LIBVA_WAYLAND
|
#ifdef HAVE_LIBVA_WAYLAND
|
||||||
m_WaylandSurface = info.info.wl.surface;
|
|
||||||
m_WaylandDisplay = info.info.wl.display;
|
|
||||||
vaDeviceContext->display = vaGetDisplayWl(info.info.wl.display);
|
vaDeviceContext->display = vaGetDisplayWl(info.info.wl.display);
|
||||||
if (!vaDeviceContext->display) {
|
if (!vaDeviceContext->display) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
@ -171,6 +169,14 @@ VAAPIRenderer::needsTestFrame()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
VAAPIRenderer::isDirectRenderingSupported()
|
||||||
|
{
|
||||||
|
// Many Wayland renderers don't support YUV surfaces, so use
|
||||||
|
// another frontend renderer to draw our frames.
|
||||||
|
return m_WindowSystem == SDL_SYSWM_X11;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VAAPIRenderer::renderFrame(AVFrame* frame)
|
VAAPIRenderer::renderFrame(AVFrame* frame)
|
||||||
{
|
{
|
||||||
|
@ -201,27 +207,10 @@ VAAPIRenderer::renderFrame(AVFrame* frame)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (m_WindowSystem == SDL_SYSWM_WAYLAND) {
|
else if (m_WindowSystem == SDL_SYSWM_WAYLAND) {
|
||||||
#ifdef HAVE_LIBVA_WAYLAND
|
// We don't support direct rendering on Wayland, so we should
|
||||||
struct wl_buffer* buffer;
|
// never get called there. Many common Wayland compositors don't
|
||||||
VAStatus status;
|
// support YUV surfaces, so direct rendering would fail.
|
||||||
|
SDL_assert(false);
|
||||||
status = vaGetSurfaceBufferWl(vaDeviceContext->display,
|
|
||||||
surface,
|
|
||||||
VA_FRAME_PICTURE,
|
|
||||||
&buffer);
|
|
||||||
if (status == VA_STATUS_SUCCESS) {
|
|
||||||
wl_surface_attach(m_WaylandSurface, buffer, 0, 0);
|
|
||||||
wl_surface_damage(m_WaylandSurface, dst.x, dst.y, dst.w, dst.h);
|
|
||||||
|
|
||||||
wl_display_flush(m_WaylandDisplay);
|
|
||||||
wl_surface_commit(m_WaylandSurface);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"vaGetSurfaceBufferWl failed(): %d",
|
|
||||||
status);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// We don't accept anything else in initialize().
|
// We don't accept anything else in initialize().
|
||||||
|
|
|
@ -34,6 +34,7 @@ public:
|
||||||
virtual bool prepareDecoderContext(AVCodecContext* context) override;
|
virtual bool prepareDecoderContext(AVCodecContext* context) override;
|
||||||
virtual void renderFrame(AVFrame* frame) override;
|
virtual void renderFrame(AVFrame* frame) override;
|
||||||
virtual bool needsTestFrame() override;
|
virtual bool needsTestFrame() override;
|
||||||
|
virtual bool isDirectRenderingSupported() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_WindowSystem;
|
int m_WindowSystem;
|
||||||
|
@ -43,11 +44,6 @@ private:
|
||||||
Window m_XWindow;
|
Window m_XWindow;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBVA_WAYLAND
|
|
||||||
struct wl_surface* m_WaylandSurface;
|
|
||||||
struct wl_display* m_WaylandDisplay;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int m_VideoWidth;
|
int m_VideoWidth;
|
||||||
int m_VideoHeight;
|
int m_VideoHeight;
|
||||||
int m_DisplayWidth;
|
int m_DisplayWidth;
|
||||||
|
|
|
@ -137,7 +137,18 @@ void FFmpegVideoDecoder::reset()
|
||||||
|
|
||||||
bool FFmpegVideoDecoder::createFrontendRenderer(PDECODER_PARAMETERS params)
|
bool FFmpegVideoDecoder::createFrontendRenderer(PDECODER_PARAMETERS params)
|
||||||
{
|
{
|
||||||
|
if (m_BackendRenderer->isDirectRenderingSupported()) {
|
||||||
|
// The backend renderer can render to the display
|
||||||
m_FrontendRenderer = m_BackendRenderer;
|
m_FrontendRenderer = m_BackendRenderer;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The backend renderer cannot directly render to the display, so
|
||||||
|
// we will create an SDL renderer to draw the frames.
|
||||||
|
m_FrontendRenderer = new SdlRenderer();
|
||||||
|
if (!m_FrontendRenderer->initialize(params)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Determine whether the frontend renderer prefers frame pacing
|
// Determine whether the frontend renderer prefers frame pacing
|
||||||
auto vsyncConstraint = m_FrontendRenderer->getFramePacingConstraint();
|
auto vsyncConstraint = m_FrontendRenderer->getFramePacingConstraint();
|
||||||
|
|
Loading…
Reference in a new issue