From 5f79a9f280d799757e6685471a83ccf23a45a704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <sebastien.blin@savoirfairelinux.com> Date: Wed, 8 Jun 2022 16:12:28 -0400 Subject: [PATCH] renderers: do not crash on update and simplify code No need to add complex mechanisms for nearly no-ops, the previous method were bugguy and caused weird crashes. Just re-create the renderer correctly. Change-Id: I88738244c7cbaa6f189799c6a28dc9244953667d --- src/app/videoprovider.cpp | 32 ++++++++++++++++++++++++-------- src/libclient/avmodel.cpp | 24 ++++++------------------ src/libclient/directrenderer.cpp | 10 ---------- src/libclient/directrenderer.h | 1 - src/libclient/renderer.cpp | 6 ------ src/libclient/renderer.h | 7 ------- src/libclient/shmrenderer.cpp | 24 ++++++++---------------- src/libclient/shmrenderer.h | 1 - 8 files changed, 38 insertions(+), 67 deletions(-) diff --git a/src/app/videoprovider.cpp b/src/app/videoprovider.cpp index d7741b770..127a89662 100644 --- a/src/app/videoprovider.cpp +++ b/src/app/videoprovider.cpp @@ -34,10 +34,26 @@ VideoProvider::VideoProvider(AVModel& avModel, QObject* parent) : QObject(parent) , avModel_(avModel) { - connect(&avModel_, &AVModel::rendererStarted, this, &VideoProvider::onRendererStarted); - connect(&avModel_, &AVModel::frameBufferRequested, this, &VideoProvider::onFrameBufferRequested); - connect(&avModel_, &AVModel::frameUpdated, this, &VideoProvider::onFrameUpdated); - connect(&avModel_, &AVModel::rendererStopped, this, &VideoProvider::onRendererStopped); + connect(&avModel_, + &AVModel::rendererStarted, + this, + &VideoProvider::onRendererStarted, + Qt::DirectConnection); + connect(&avModel_, + &AVModel::frameBufferRequested, + this, + &VideoProvider::onFrameBufferRequested, + Qt::DirectConnection); + connect(&avModel_, + &AVModel::frameUpdated, + this, + &VideoProvider::onFrameUpdated, + Qt::DirectConnection); + connect(&avModel_, + &AVModel::rendererStopped, + this, + &VideoProvider::onRendererStopped, + Qt::DirectConnection); } void @@ -95,10 +111,10 @@ VideoProvider::captureVideoFrame(const QString& id) auto imageFormat = QVideoFrameFormat::imageFormatFromPixelFormat( QVideoFrameFormat::Format_RGBA8888); auto img = QImage(videoFrame->bits(0), - videoFrame->width(), - videoFrame->height(), - videoFrame->bytesPerLine(0), - imageFormat); + videoFrame->width(), + videoFrame->height(), + videoFrame->bytesPerLine(0), + imageFormat); return Utils::byteArrayToBase64String(Utils::QImageToByteArray(img)); } return {}; diff --git a/src/libclient/avmodel.cpp b/src/libclient/avmodel.cpp index 088ff0e25..0254eb0dd 100644 --- a/src/libclient/avmodel.cpp +++ b/src/libclient/avmodel.cpp @@ -872,24 +872,12 @@ AVModelPimpl::addRenderer(const QString& id, const QSize& res, const QString& sh Qt::DirectConnection); }; std::lock_guard<std::mutex> lk(renderers_mtx_); - Renderer* renderer {nullptr}; - auto it = renderers_.find(id); - if (it == renderers_.end()) { - renderers_.emplace(id, createRenderer(id, res, shmPath)); - renderer = renderers_.at(id).get(); - connectRenderer(renderer, id); - renderer->startRendering(); - } else { - renderer = it->second.get(); - if (renderer) { - renderer->update(res, shmPath); - } else { - it->second.reset(createRenderer(id, res, shmPath).get()); - renderer = it->second.get(); - connectRenderer(renderer, id); - renderer->startRendering(); - } - } + renderers_.erase(id); // Because it should be done before creating the renderer + auto renderer = createRenderer(id, res, shmPath); + auto& r = renderers_[id]; + r = std::move(renderer); + connectRenderer(r.get(), id); + r->startRendering(); } } diff --git a/src/libclient/directrenderer.cpp b/src/libclient/directrenderer.cpp index f3d838326..c6078340e 100644 --- a/src/libclient/directrenderer.cpp +++ b/src/libclient/directrenderer.cpp @@ -112,16 +112,6 @@ DirectRenderer::stopRendering() Q_EMIT stopped(); } -void -DirectRenderer::update(const QSize& res, const QString&) -{ - stopRendering(); - Renderer::update(res); - - VideoManager::instance().registerSinkTarget(id(), pimpl_->target); - startRendering(); -} - Frame DirectRenderer::currentFrame() const { diff --git a/src/libclient/directrenderer.h b/src/libclient/directrenderer.h index dfcd02659..3db7d2859 100644 --- a/src/libclient/directrenderer.h +++ b/src/libclient/directrenderer.h @@ -33,7 +33,6 @@ public: ~DirectRenderer(); // Renderer interface. - void update(const QSize& res, const QString& shmPath) override; lrc::api::video::Frame currentFrame() const override; public Q_SLOTS: diff --git a/src/libclient/renderer.cpp b/src/libclient/renderer.cpp index 3a2065fd1..22f6fea4a 100644 --- a/src/libclient/renderer.cpp +++ b/src/libclient/renderer.cpp @@ -46,11 +46,5 @@ Renderer::size() const return size_; } -void -Renderer::update(const QSize& size, const QString&) -{ - size_ = size; -} - } // namespace video } // namespace lrc diff --git a/src/libclient/renderer.h b/src/libclient/renderer.h index 9e91bc29f..7cba0f9ef 100644 --- a/src/libclient/renderer.h +++ b/src/libclient/renderer.h @@ -49,13 +49,6 @@ public: */ QSize size() const; - /** - * Update size and shmPath of a renderer - * @param size new renderer dimensions - * @param shmPath new shmPath - */ - virtual void update(const QSize& size, const QString& shmPath = {}); - /** * @return current rendered frame */ diff --git a/src/libclient/shmrenderer.cpp b/src/libclient/shmrenderer.cpp index 8bbd2947d..bdd4eee25 100644 --- a/src/libclient/shmrenderer.cpp +++ b/src/libclient/shmrenderer.cpp @@ -114,10 +114,16 @@ public: constexpr static const int FRAME_CHECK_RATE_HZ = 120; // Lock the memory while the copy is being made - bool shmLock() { return ::sem_wait(&shmArea->mutex) >= 0; }; + bool shmLock() + { + return ::sem_wait(&shmArea->mutex) >= 0; + }; // Remove the lock, allow a new frame to be drawn - void shmUnlock() { ::sem_post(&shmArea->mutex); }; + void shmUnlock() + { + ::sem_post(&shmArea->mutex); + }; // Wait for new frame data from shared memory and save pointer. bool getNewFrame(bool wait) @@ -242,20 +248,6 @@ ShmRenderer::~ShmRenderer() stopShm(); } -void -ShmRenderer::update(const QSize& res, const QString& shmPath) -{ - Q_EMIT stopped(); - Renderer::update(res); - - if (!pimpl_->thread.isRunning()) - pimpl_->thread.start(); - - pimpl_->path = shmPath; - VideoManager::instance().startShmSink(id(), true); - Q_EMIT started(); -} - Frame ShmRenderer::currentFrame() const { diff --git a/src/libclient/shmrenderer.h b/src/libclient/shmrenderer.h index 7880432a1..3514a6ecb 100644 --- a/src/libclient/shmrenderer.h +++ b/src/libclient/shmrenderer.h @@ -32,7 +32,6 @@ public: ~ShmRenderer(); // Renderer interface. - void update(const QSize& res, const QString& shmPath) override; lrc::api::video::Frame currentFrame() const override; void stopShm(); -- GitLab