Skip to content
Snippets Groups Projects
Commit 1943cda2 authored by Andreas Traczyk's avatar Andreas Traczyk
Browse files

avmodel: use QReadWriteLock instead of QMutex

Change-Id: I27a829e6b6b57fbe31fc3fcf49fce4ba2bfaf168
parent 9a582980
No related branches found
No related tags found
No related merge requests found
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QUrl> #include <QUrl>
#include <QSize> #include <QSize>
#include <QReadWriteLock>
#include <algorithm> // std::sort #include <algorithm> // std::sort
#include <chrono> #include <chrono>
...@@ -75,7 +76,7 @@ public: ...@@ -75,7 +76,7 @@ public:
static const QString recorderSavesSubdir; static const QString recorderSavesSubdir;
AVModel& linked_; AVModel& linked_;
std::mutex renderers_mtx_; QReadWriteLock renderersMutex_;
std::map<QString, std::unique_ptr<Renderer>> renderers_; std::map<QString, std::unique_ptr<Renderer>> renderers_;
QString currentVideoCaptureDevice_ {}; QString currentVideoCaptureDevice_ {};
...@@ -166,7 +167,7 @@ AVModel::AVModel(const CallbacksHandler& callbacksHandler) ...@@ -166,7 +167,7 @@ AVModel::AVModel(const CallbacksHandler& callbacksHandler)
AVModel::~AVModel() AVModel::~AVModel()
{ {
std::lock_guard<std::mutex> lk(pimpl_->renderers_mtx_); QWriteLocker lk(&pimpl_->renderersMutex_);
for (auto r = pimpl_->renderers_.begin(); r != pimpl_->renderers_.end(); ++r) { for (auto r = pimpl_->renderers_.begin(); r != pimpl_->renderers_.end(); ++r) {
(*r).second.reset(); (*r).second.reset();
} }
...@@ -176,7 +177,7 @@ QList<MapStringString> ...@@ -176,7 +177,7 @@ QList<MapStringString>
AVModel::getRenderersInfo(QString id) AVModel::getRenderersInfo(QString id)
{ {
QList<MapStringString> infoList; QList<MapStringString> infoList;
std::lock_guard<std::mutex> lk(pimpl_->renderers_mtx_); QReadLocker lk(&pimpl_->renderersMutex_);
for (auto r = pimpl_->renderers_.begin(); r != pimpl_->renderers_.end(); r++) { for (auto r = pimpl_->renderers_.begin(); r != pimpl_->renderers_.end(); r++) {
MapStringString qmap; MapStringString qmap;
auto& rend = r->second; auto& rend = r->second;
...@@ -195,14 +196,17 @@ AVModel::getRenderersInfo(QString id) ...@@ -195,14 +196,17 @@ AVModel::getRenderersInfo(QString id)
void void
AVModel::updateRenderersFPSInfo(QString rendererId) AVModel::updateRenderersFPSInfo(QString rendererId)
{ {
std::unique_lock<std::mutex> lk(pimpl_->renderers_mtx_); QReadLocker lk(&pimpl_->renderersMutex_);
auto it = std::find_if(pimpl_->renderers_.begin(), auto it = std::find_if(pimpl_->renderers_.begin(),
pimpl_->renderers_.end(), pimpl_->renderers_.end(),
[&rendererId](const auto& c) { [&rendererId](const auto& c) {
return rendererId == c.second->getInfos()["RENDERER_ID"]; return rendererId == c.second->getInfos()["RENDERER_ID"];
}); });
if (it != pimpl_->renderers_.end()) if (it != pimpl_->renderers_.end()) {
Q_EMIT onRendererFpsChange(qMakePair(rendererId, it->second->getInfos()["FPS"])); auto fpsInfo = qMakePair(rendererId, it->second->getInfos()["FPS"]);
lk.unlock();
Q_EMIT onRendererFpsChange(fpsInfo);
}
} }
bool bool
...@@ -333,7 +337,7 @@ AVModel::setDeviceSettings(video::Settings& settings) ...@@ -333,7 +337,7 @@ AVModel::setDeviceSettings(video::Settings& settings)
// If the preview is running, reload it // If the preview is running, reload it
// doing this during a call will cause re-invite, this is unwanted // doing this during a call will cause re-invite, this is unwanted
std::unique_lock<std::mutex> lk(pimpl_->renderers_mtx_); QReadLocker lk(&pimpl_->renderersMutex_);
auto it = pimpl_->renderers_.find(video::PREVIEW_RENDERER_ID); auto it = pimpl_->renderers_.find(video::PREVIEW_RENDERER_ID);
if (it != pimpl_->renderers_.end() && it->second && pimpl_->renderers_.size() == 1) { if (it != pimpl_->renderers_.end() && it->second && pimpl_->renderers_.size() == 1) {
lk.unlock(); lk.unlock();
...@@ -942,54 +946,63 @@ createRenderer(const QString& id, const QSize& res, const QString& shmPath = {}) ...@@ -942,54 +946,63 @@ createRenderer(const QString& id, const QSize& res, const QString& shmPath = {})
void void
AVModelPimpl::addRenderer(const QString& id, const QSize& res, const QString& shmPath) AVModelPimpl::addRenderer(const QString& id, const QSize& res, const QString& shmPath)
{ {
// Remove the renderer if it already exists.
removeRenderer(id); // Will write-lock renderersMutex_.
{ {
std::lock_guard<std::mutex> lk(renderers_mtx_); QWriteLocker lk(&renderersMutex_);
renderers_[id] = createRenderer(id, res, shmPath); renderers_[id] = createRenderer(id, res, shmPath);
} }
auto& r = renderers_[id]; QReadLocker lk(&renderersMutex_);
auto it = renderers_.find(id);
// Listen and forward id-bound signals upwards. if (it == renderers_.end()) {
connect( qWarning() << Q_FUNC_INFO << "Renderer not found for id:" << id;
r.get(), return;
&Renderer::fpsChanged, }
this,
[this, id](void) { linked_.updateRenderersFPSInfo(id); }, if (auto* renderer = it->second.get()) {
Qt::QueuedConnection); connect(
connect( renderer,
r.get(), &Renderer::fpsChanged,
&Renderer::started, this,
this, [this, id](void) { linked_.updateRenderersFPSInfo(id); },
[this, id](const QSize& size) { Q_EMIT linked_.rendererStarted(id, size); }, Qt::QueuedConnection);
Qt::DirectConnection); connect(
renderer,
&Renderer::started,
this,
[this, id](const QSize& size) { Q_EMIT linked_.rendererStarted(id, size); },
Qt::DirectConnection);
#ifdef ENABLE_LIBWRAP #ifdef ENABLE_LIBWRAP
connect( connect(
r.get(), renderer,
&Renderer::frameBufferRequested, &Renderer::frameBufferRequested,
this, this,
[this, id](AVFrame* frame) { Q_EMIT linked_.frameBufferRequested(id, frame); }, [this, id](AVFrame* frame) { Q_EMIT linked_.frameBufferRequested(id, frame); },
Qt::DirectConnection); Qt::DirectConnection);
#endif #endif
connect( connect(
r.get(), renderer,
&Renderer::frameUpdated, &Renderer::frameUpdated,
this, this,
[this, id] { Q_EMIT linked_.frameUpdated(id); }, [this, id] { Q_EMIT linked_.frameUpdated(id); },
Qt::DirectConnection); Qt::DirectConnection);
connect( connect(
r.get(), renderer,
&Renderer::stopped, &Renderer::stopped,
this, this,
[this, id] { Q_EMIT linked_.rendererStopped(id); }, [this, id] { Q_EMIT linked_.rendererStopped(id); },
Qt::DirectConnection); Qt::DirectConnection);
r->startRendering(); renderer->startRendering();
}
} }
void void
AVModelPimpl::removeRenderer(const QString& id) AVModelPimpl::removeRenderer(const QString& id)
{ {
std::lock_guard<std::mutex> lk(renderers_mtx_); QWriteLocker lk(&renderersMutex_);
auto it = renderers_.find(id); auto it = renderers_.find(id);
if (it == renderers_.end()) { if (it == renderers_.end()) {
qWarning() << "Cannot remove renderer. " << id << "not found"; qWarning() << "Cannot remove renderer. " << id << "not found";
...@@ -1001,14 +1014,14 @@ AVModelPimpl::removeRenderer(const QString& id) ...@@ -1001,14 +1014,14 @@ AVModelPimpl::removeRenderer(const QString& id)
bool bool
AVModelPimpl::hasRenderer(const QString& id) AVModelPimpl::hasRenderer(const QString& id)
{ {
std::lock_guard<std::mutex> lk(renderers_mtx_); QReadLocker lk(&renderersMutex_);
return renderers_.find(id) != renderers_.end(); return renderers_.find(id) != renderers_.end();
} }
QSize QSize
AVModelPimpl::getRendererSize(const QString& id) AVModelPimpl::getRendererSize(const QString& id)
{ {
std::lock_guard<std::mutex> lk(renderers_mtx_); QReadLocker lk(&renderersMutex_);
auto it = renderers_.find(id); auto it = renderers_.find(id);
if (it != renderers_.end()) { if (it != renderers_.end()) {
return it->second->size(); return it->second->size();
...@@ -1019,7 +1032,7 @@ AVModelPimpl::getRendererSize(const QString& id) ...@@ -1019,7 +1032,7 @@ AVModelPimpl::getRendererSize(const QString& id)
Frame Frame
AVModelPimpl::getRendererFrame(const QString& id) AVModelPimpl::getRendererFrame(const QString& id)
{ {
std::lock_guard<std::mutex> lk(renderers_mtx_); QReadLocker lk(&renderersMutex_);
auto it = renderers_.find(id); auto it = renderers_.find(id);
if (it != renderers_.end()) { if (it != renderers_.end()) {
return it->second->currentFrame(); return it->second->currentFrame();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment