Commit 5f79a9f2 authored by Sébastien Blin's avatar Sébastien Blin
Browse files

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
parent b70c0fe5
......@@ -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 {};
......
......@@ -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();
}
}
......
......@@ -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
{
......
......@@ -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:
......
......@@ -46,11 +46,5 @@ Renderer::size() const
return size_;
}
void
Renderer::update(const QSize& size, const QString&)
{
size_ = size;
}
} // namespace video
} // namespace lrc
......@@ -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
*/
......
......@@ -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
{
......
......@@ -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();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment