diff --git a/src/plugins/screencast/screencaststream.cpp b/src/plugins/screencast/screencaststream.cpp index 6f76f3713e..1efb0904f5 100644 --- a/src/plugins/screencast/screencaststream.cpp +++ b/src/plugins/screencast/screencaststream.cpp @@ -240,6 +240,8 @@ void ScreenCastStream::onStreamAddBuffer(void *data, pw_buffer *buffer) } #endif } + + stream->m_waitForNewBuffers = false; } void ScreenCastStream::onStreamRemoveBuffer(void *data, pw_buffer *buffer) @@ -259,6 +261,15 @@ void ScreenCastStream::onStreamRemoveBuffer(void *data, pw_buffer *buffer) } } +void ScreenCastStream::onStreamRenegotiateFormat(void *data, uint64_t) +{ + ScreenCastStream *stream = static_cast(data); + + char buffer[2048]; + auto params = stream->buildFormats(stream->m_dmabufParams.has_value(), buffer); + pw_stream_update_params(stream->pwStream, params.data(), params.count()); +} + ScreenCastStream::ScreenCastStream(ScreenCastSource *source, QObject *parent) : QObject(parent) , m_source(source) @@ -297,6 +308,8 @@ bool ScreenCastStream::init() return false; } + pwRenegotiate = pw_loop_add_event(pwCore.get()->pwMainLoop, onStreamRenegotiateFormat, this); + return true; } @@ -373,10 +386,17 @@ void ScreenCastStream::recordFrame(const QRegion &_damagedRegion) return; } + if (m_waitForNewBuffers) { + qCWarning(KWIN_SCREENCAST) << "Waiting for new buffers to be created"; + return; + } + const auto size = m_source->textureSize(); if (size != m_resolution) { m_resolution = size; - newStreamParams(); + m_waitForNewBuffers = true; + m_dmabufParams = std::nullopt; + pw_loop_signal_event(pwCore.get()->pwMainLoop, pwRenegotiate); return; } diff --git a/src/plugins/screencast/screencaststream.h b/src/plugins/screencast/screencaststream.h index c6483fd8bc..0de382152e 100644 --- a/src/plugins/screencast/screencaststream.h +++ b/src/plugins/screencast/screencaststream.h @@ -74,6 +74,7 @@ private: static void onStreamStateChanged(void *data, pw_stream_state old, pw_stream_state state, const char *error_message); static void onStreamAddBuffer(void *data, pw_buffer *buffer); static void onStreamRemoveBuffer(void *data, pw_buffer *buffer); + static void onStreamRenegotiateFormat(void *data, uint64_t); bool createStream(); QVector buildFormats(bool fixate, char buffer[2048]); @@ -92,6 +93,7 @@ private: std::shared_ptr pwCore; std::unique_ptr m_source; struct pw_stream *pwStream = nullptr; + struct spa_source *pwRenegotiate = nullptr; spa_hook streamListener; pw_stream_events pwStreamEvents = {}; @@ -126,6 +128,7 @@ private: std::optional m_start; quint64 m_sequential = 0; bool m_hasDmaBuf = false; + bool m_waitForNewBuffers = false; }; } // namespace KWin