Skip to content
Snippets Groups Projects
Commit 84427f24 authored by Emmanuel Lepage Vallee's avatar Emmanuel Lepage Vallee
Browse files

[ #30520 ] Be even more carefull to prevent deaklock and races

parent ec3a7170
No related branches found
No related tags found
No related merge requests found
...@@ -881,6 +881,7 @@ void Call::nothing() ...@@ -881,6 +881,7 @@ void Call::nothing()
void Call::error() void Call::error()
{ {
if (videoRenderer()) { if (videoRenderer()) {
//Well, in this case we have no choice, it still doesn't belong here
videoRenderer()->stopRendering(); videoRenderer()->stopRendering();
} }
throw QString("There was an error handling your call, please restart SFLPhone.Is you encounter this problem often, \ throw QString("There was an error handling your call, please restart SFLPhone.Is you encounter this problem often, \
...@@ -950,7 +951,7 @@ void Call::hangUp() ...@@ -950,7 +951,7 @@ void Call::hangUp()
m_pStopTimeStamp = curTime; m_pStopTimeStamp = curTime;
qDebug() << "Hanging up call. callId : " << m_CallId << "ConfId:" << m_ConfId; qDebug() << "Hanging up call. callId : " << m_CallId << "ConfId:" << m_ConfId;
bool ret; bool ret;
if (videoRenderer()) { if (videoRenderer()) { //TODO remove, cheap hack
videoRenderer()->stopRendering(); videoRenderer()->stopRendering();
} }
if (!isConference()) if (!isConference())
...@@ -1091,7 +1092,7 @@ void Call::startStop() ...@@ -1091,7 +1092,7 @@ void Call::startStop()
void Call::stop() void Call::stop()
{ {
qDebug() << "Stoping call. callId : " << m_CallId << "ConfId:" << m_ConfId; qDebug() << "Stoping call. callId : " << m_CallId << "ConfId:" << m_ConfId;
if (videoRenderer()) { if (videoRenderer()) { //TODO remove, cheap hack
videoRenderer()->stopRendering(); videoRenderer()->stopRendering();
} }
time_t curTime; time_t curTime;
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
VideoModel* VideoModel::m_spInstance = nullptr; VideoModel* VideoModel::m_spInstance = nullptr;
///Constructor ///Constructor
VideoModel::VideoModel():QObject(),m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false),m_Thread(this) VideoModel::VideoModel():QThread(),m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false)
{ {
VideoInterface& interface = DBus::VideoManager::instance(); VideoInterface& interface = DBus::VideoManager::instance();
connect( &interface , SIGNAL(deviceEvent()) , this, SLOT(deviceEvent()) ); connect( &interface , SIGNAL(deviceEvent()) , this, SLOT(deviceEvent()) );
...@@ -104,15 +104,15 @@ void VideoModel::startedDecoding(const QString& id, const QString& shmPath, int ...@@ -104,15 +104,15 @@ void VideoModel::startedDecoding(const QString& id, const QString& shmPath, int
if (m_lRenderers[id] == nullptr ) { if (m_lRenderers[id] == nullptr ) {
m_lRenderers[id] = new VideoRenderer(id,shmPath,Resolution(width,height)); m_lRenderers[id] = new VideoRenderer(id,shmPath,Resolution(width,height));
m_lRenderers[id]->moveToThread(&m_Thread); m_lRenderers[id]->moveToThread(this);
if (!isRunning())
start();
} }
else { else {
VideoRenderer* renderer = m_lRenderers[id]; VideoRenderer* renderer = m_lRenderers[id];
renderer->setShmPath(shmPath); renderer->setShmPath(shmPath);
renderer->setResolution(QSize(width,height)); renderer->setResolution(QSize(width,height));
} }
if (!m_Thread.isRunning())
m_Thread.start();
m_lRenderers[id]->startRendering(); m_lRenderers[id]->startRendering();
if (id != "local") { if (id != "local") {
...@@ -129,8 +129,13 @@ void VideoModel::stoppedDecoding(const QString& id, const QString& shmPath) ...@@ -129,8 +129,13 @@ void VideoModel::stoppedDecoding(const QString& id, const QString& shmPath)
if ( r ) { if ( r ) {
r->stopRendering(); r->stopRendering();
} }
qDebug() << "Video stopped for call" << id << "Renderer found:" << (m_lRenderers[id] != nullptr);
m_lRenderers[id] = nullptr; m_lRenderers[id] = nullptr;
delete r; delete r;
qDebug() << "Video stopped for call" << id << "Renderer found:" << (m_lRenderers[id] != nullptr);
emit videoStopped(); emit videoStopped();
} }
void VideoModel::run()
{
exec();
}
...@@ -31,7 +31,7 @@ class Call; ...@@ -31,7 +31,7 @@ class Call;
struct SHMHeader; struct SHMHeader;
///VideoModel: Video event dispatcher ///VideoModel: Video event dispatcher
class LIB_EXPORT VideoModel : public QObject { class LIB_EXPORT VideoModel : public QThread {
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
Q_OBJECT Q_OBJECT
...@@ -48,6 +48,9 @@ public: ...@@ -48,6 +48,9 @@ public:
//Setters //Setters
void setBufferSize(uint size); void setBufferSize(uint size);
protected:
void run();
private: private:
//Constructor //Constructor
VideoModel(); VideoModel();
...@@ -60,7 +63,6 @@ private: ...@@ -60,7 +63,6 @@ private:
uint m_BufferSize ; uint m_BufferSize ;
uint m_ShmKey ; uint m_ShmKey ;
uint m_SemKey ; uint m_SemKey ;
QThread m_Thread ;
QHash<QString,VideoRenderer*> m_lRenderers; QHash<QString,VideoRenderer*> m_lRenderers;
public Q_SLOTS: public Q_SLOTS:
......
...@@ -71,15 +71,14 @@ VideoRenderer::~VideoRenderer() ...@@ -71,15 +71,14 @@ VideoRenderer::~VideoRenderer()
} }
///Get the data from shared memory and transform it into a QByteArray ///Get the data from shared memory and transform it into a QByteArray
QByteArray VideoRenderer::renderToBitmap(QByteArray& data,bool& ok) bool VideoRenderer::renderToBitmap(QByteArray& data)
{ {
if (!m_isRendering) { if (!m_isRendering) {
return QByteArray(); return false;
} }
if (!shmLock()) { if (!shmLock()) {
ok = false; return false;
return QByteArray();
} }
// wait for a new buffer // wait for a new buffer
...@@ -111,20 +110,17 @@ QByteArray VideoRenderer::renderToBitmap(QByteArray& data,bool& ok) ...@@ -111,20 +110,17 @@ QByteArray VideoRenderer::renderToBitmap(QByteArray& data,bool& ok)
// break; // break;
// } // }
if (err < 0) { if (err < 0) {
ok = false; return false;
return QByteArray();
} }
if (!shmLock()) { if (!shmLock()) {
ok = false; return false;
return QByteArray();
} }
} }
if (!resizeShm()) { if (!resizeShm()) {
qDebug() << "Could not resize shared memory"; qDebug() << "Could not resize shared memory";
ok = false; return false;
return QByteArray();
} }
if (data.size() != m_pShmArea->m_BufferSize) if (data.size() != m_pShmArea->m_BufferSize)
...@@ -132,7 +128,8 @@ QByteArray VideoRenderer::renderToBitmap(QByteArray& data,bool& ok) ...@@ -132,7 +128,8 @@ QByteArray VideoRenderer::renderToBitmap(QByteArray& data,bool& ok)
memcpy(data.data(),m_pShmArea->m_Data,m_pShmArea->m_BufferSize); memcpy(data.data(),m_pShmArea->m_Data,m_pShmArea->m_BufferSize);
m_BufferGen = m_pShmArea->m_BufferGen; m_BufferGen = m_pShmArea->m_BufferGen;
shmUnlock(); shmUnlock();
return data; // return data;
return true;
} }
///Connect to the shared memory ///Connect to the shared memory
...@@ -243,9 +240,9 @@ timespec VideoRenderer::createTimeout() ...@@ -243,9 +240,9 @@ timespec VideoRenderer::createTimeout()
///Update the buffer ///Update the buffer
void VideoRenderer::timedEvents() void VideoRenderer::timedEvents()
{ {
bool ok = true;
m_pMutex->lock(); m_pMutex->lock();
renderToBitmap(m_Frame,ok);
bool ok = renderToBitmap(m_Frame);
m_pMutex->unlock(); m_pMutex->unlock();
if (ok == true) { if (ok == true) {
emit frameUpdated(); emit frameUpdated();
...@@ -294,7 +291,7 @@ void VideoRenderer::stopRendering() ...@@ -294,7 +291,7 @@ void VideoRenderer::stopRendering()
///Get the raw bytes directly from the SHM, not recommended, but optimal ///Get the raw bytes directly from the SHM, not recommended, but optimal
const char* VideoRenderer::rawData() const char* VideoRenderer::rawData()
{ {
return m_isRendering?m_pShmArea->m_Data:nullptr; return m_isRendering?m_Frame.data():nullptr;
} }
///Is this redenrer active ///Is this redenrer active
......
...@@ -48,7 +48,6 @@ class LIB_EXPORT VideoRenderer : public QObject { ...@@ -48,7 +48,6 @@ class LIB_EXPORT VideoRenderer : public QObject {
bool startShm (); bool startShm ();
//Getters //Getters
QByteArray renderToBitmap(QByteArray& data, bool& ok);
const char* rawData (); const char* rawData ();
bool isRendering (); bool isRendering ();
QByteArray currentFrame (); QByteArray currentFrame ();
...@@ -82,6 +81,7 @@ class LIB_EXPORT VideoRenderer : public QObject { ...@@ -82,6 +81,7 @@ class LIB_EXPORT VideoRenderer : public QObject {
timespec createTimeout(); timespec createTimeout();
bool shmLock (); bool shmLock ();
void shmUnlock (); void shmUnlock ();
bool renderToBitmap(QByteArray& data);
private Q_SLOTS: private Q_SLOTS:
void timedEvents(); void timedEvents();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment