screencast: Discard pending buffer and fence if stream state changes

While the changes made earlier prevent enqueueing buffers when the
stream is not in a streaming state, screencasting continued to crash.
The reason for that seems to be that pipewire will, in certain cases,
invalidate some buffers, including the buffer that we are currently
tracking as "pending buffer". The result of this is that when we then
try to enqueue that buffer, we get a crash.

To prevent this, discard the pending buffer when the stream state
changes. Since that makes the pending fence useless as well, also
discard it and its notifier.
This commit is contained in:
Arjen Hiemstra 2023-05-23 13:15:58 +02:00 committed by Vlad Zahorodnii
parent aedd67ef4b
commit 8d0e1b290a

View file

@ -77,6 +77,10 @@ void ScreenCastStream::onStreamStateChanged(void *data, pw_stream_state old, pw_
qCDebug(KWIN_SCREENCAST) << "state changed" << pw_stream_state_as_string(old) << " -> " << pw_stream_state_as_string(state) << error_message; qCDebug(KWIN_SCREENCAST) << "state changed" << pw_stream_state_as_string(old) << " -> " << pw_stream_state_as_string(state) << error_message;
pw->m_streaming = false; pw->m_streaming = false;
pw->m_pendingBuffer = nullptr;
pw->m_pendingNotifier.reset();
pw->m_pendingFence.reset();
switch (state) { switch (state) {
case PW_STREAM_STATE_ERROR: case PW_STREAM_STATE_ERROR:
qCWarning(KWIN_SCREENCAST) << "Stream error: " << error_message; qCWarning(KWIN_SCREENCAST) << "Stream error: " << error_message;
@ -90,9 +94,6 @@ void ScreenCastStream::onStreamStateChanged(void *data, pw_stream_state old, pw_
case PW_STREAM_STATE_STREAMING: case PW_STREAM_STATE_STREAMING:
pw->m_streaming = true; pw->m_streaming = true;
Q_EMIT pw->startStreaming(); Q_EMIT pw->startStreaming();
if (pw->m_pendingBuffer) {
pw->tryEnqueue(pw->m_pendingBuffer);
}
break; break;
case PW_STREAM_STATE_CONNECTING: case PW_STREAM_STATE_CONNECTING:
break; break;