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:
parent
75720785a0
commit
47732c54b6
2 changed files with 24 additions and 1 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue