Screencast: properly renegotiate stream when window size changes

We need to completely renegotiate stream parameters in case of window
size gets changed, otherwise no renegotiation will happen and clients
will not accommodate to our changes.

Fixes: https://github.com/obsproject/obs-studio/issues/7875
This commit is contained in:
Jan Grulich 2022-12-02 15:56:24 +01:00 committed by Aleix Pol Gonzalez
parent 75720785a0
commit 47732c54b6
2 changed files with 24 additions and 1 deletions

View file

@ -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<ScreenCastStream *>(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;
}

View file

@ -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<const spa_pod *> buildFormats(bool fixate, char buffer[2048]);
@ -92,6 +93,7 @@ private:
std::shared_ptr<PipeWireCore> pwCore;
std::unique_ptr<ScreenCastSource> 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<std::chrono::nanoseconds> m_start;
quint64 m_sequential = 0;
bool m_hasDmaBuf = false;
bool m_waitForNewBuffers = false;
};
} // namespace KWin