[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [sflphone-kde/contact_refactor] src: [ #44095 ] Implement a video flip-buffer, use double buffer ins
From:       Emmanuel Lepage Vallee <emmanuel.lepage () savoirfairelinux ! com>
Date:       2014-03-31 16:58:29
Message-ID: E1WUfXZ-0000Ha-1i () scm ! kde ! org
[Download RAW message or body]

Git commit 331f6777b218c7bfd50014acb9be4eb50306d60b by Emmanuel Lepage Vallee.
Committed on 31/03/2014 at 16:58.
Pushed by lepagevalleeemmanuel into branch 'contact_refactor'.

[ #44095 ] Implement a video flip-buffer, use double buffer instead of triple ones

M  +2    -1    src/klib/minimalhistorybackend.cpp
M  +14   -5    src/lib/videomodel.cpp
M  +4    -1    src/lib/videomodel.h
M  +33   -16   src/lib/videorenderer.cpp
M  +4    -2    src/lib/videorenderer.h
M  +3    -12   src/widgets/videoglframe.cpp

http://commits.kde.org/sflphone-kde/331f6777b218c7bfd50014acb9be4eb50306d60b

diff --git a/src/klib/minimalhistorybackend.cpp b/src/klib/minimalhistorybackend.cpp
index 0a84429..e4424c3 100644
--- a/src/klib/minimalhistorybackend.cpp
+++ b/src/klib/minimalhistorybackend.cpp
@@ -107,10 +107,11 @@ bool MinimalHistoryBackend::append(const Call* call)
       const QString direction = (call->direction()==Call::Direction::INCOMING)?
          Call::HistoryStateName::INCOMING : Call::HistoryStateName::OUTGOING;
       QTextStream streamFileOut(&file);
+      const Account* a = call->account();
       streamFileOut << QString("%1=%2\n").arg(Call::HistoryMapFields::CALLID         \
                ).arg(call->id()                     );
       streamFileOut << \
QString("%1=%2\n").arg(Call::HistoryMapFields::TIMESTAMP_START \
                ).arg(call->startTimeStamp()         );
       streamFileOut << QString("%1=%2\n").arg(Call::HistoryMapFields::TIMESTAMP_STOP \
                ).arg(call->stopTimeStamp()          );
-      streamFileOut << QString("%1=%2\n").arg(Call::HistoryMapFields::ACCOUNT_ID     \
).arg(call->account()->id()          ); +      streamFileOut << \
QString("%1=%2\n").arg(Call::HistoryMapFields::ACCOUNT_ID      ).arg(a?a->id():""     \
                );
       streamFileOut << QString("%1=%2\n").arg(Call::HistoryMapFields::DISPLAY_NAME   \
                ).arg(call->peerName()               );
       streamFileOut << QString("%1=%2\n").arg(Call::HistoryMapFields::PEER_NUMBER    \
                ).arg(call->peerPhoneNumber()->uri() );
       streamFileOut << QString("%1=%2\n").arg(Call::HistoryMapFields::DIRECTION      \
                ).arg(direction                      );
diff --git a/src/lib/videomodel.cpp b/src/lib/videomodel.cpp
index b800837..90d64c0 100644
--- a/src/lib/videomodel.cpp
+++ b/src/lib/videomodel.cpp
@@ -17,6 +17,9 @@
  ***************************************************************************/
 #include "videomodel.h"
 
+//Qt
+#include <QtCore/QMutex>
+
 //SFLPhone
 #include "dbus/videomanager.h"
 #include "videodevice.h"
@@ -28,7 +31,7 @@
 VideoModel* VideoModel::m_spInstance = nullptr;
 
 ///Constructor
-VideoModel::VideoModel():QThread(),m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false)
 +VideoModel::VideoModel():QThread(),m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false),m_SSMutex(new \
QMutex())  {
    VideoInterface& interface = DBus::VideoManager::instance();
    connect( &interface , SIGNAL(deviceEvent())                           , this, \
SLOT(deviceEvent())                           ); @@ -164,10 +167,10 @@ void \
VideoModel::stoppedDecoding(const QString& id, const QString& shmPath)  delete r;
 }
 
-void VideoModel::run()
-{
-   exec();
-}
+// void VideoModel::run()
+// {
+//    exec();
+// }
 
 
 void VideoModel::setActiveDevice(const VideoDevice* device)
@@ -224,3 +227,9 @@ VideoDevice* VideoModel::device(const QString &id)
 {
    return m_hDevices[id];
 }
+
+QMutex* VideoModel::startStopMutex() const
+{
+   return m_SSMutex;
+}
+
diff --git a/src/lib/videomodel.h b/src/lib/videomodel.h
index b23006c..6117df9 100644
--- a/src/lib/videomodel.h
+++ b/src/lib/videomodel.h
@@ -28,6 +28,7 @@
 #include "videodevice.h"
 class VideoRenderer;
 class Call;
+class QMutex;
 struct SHMHeader;
 
 ///VideoModel: Video event dispatcher
@@ -47,6 +48,7 @@ public:
    QList<VideoDevice*> devices();
    VideoDevice* activeDevice() const;
    VideoDevice* device(const QString &id);
+   QMutex* startStopMutex() const;
 
    //Setters
    void setBufferSize(uint size);
@@ -54,7 +56,7 @@ public:
    void switchDevice(const VideoDevice* device) const;
 
 protected:
-   void run();
+//    void run();
 
 private:
    //Constructor
@@ -69,6 +71,7 @@ private:
    uint           m_BufferSize  ;
    uint           m_ShmKey      ;
    uint           m_SemKey      ;
+   QMutex*        m_SSMutex     ;
    QHash<QString,VideoRenderer*> m_lRenderers;
    QHash<QString,VideoDevice*>   m_hDevices  ;
 
diff --git a/src/lib/videorenderer.cpp b/src/lib/videorenderer.cpp
index d221e69..89cd560 100644
--- a/src/lib/videorenderer.cpp
+++ b/src/lib/videorenderer.cpp
@@ -19,6 +19,7 @@
 
 #include <QtCore/QDebug>
 #include <QtCore/QMutex>
+#include <QtCore/QThread>
 
 #include <sys/ipc.h>
 #include <sys/sem.h>
@@ -36,6 +37,7 @@
 #endif
 
 #include <QtCore/QTimer>
+#include "videomodel.h"
 
 ///Shared memory object
 struct SHMHeader{
@@ -58,7 +60,7 @@ VideoRenderer::VideoRenderer(const QString& id, const QString& \
shmPath, Resoluti  m_Width(res.width()), m_Height(res.height()), m_ShmPath(shmPath), \
fd(-1),  m_pShmArea((SHMHeader*)MAP_FAILED), m_ShmAreaLen(0), m_BufferGen(0),
    m_isRendering(false),m_pTimer(nullptr),m_Res(res),m_pMutex(new QMutex()),
-   m_Id(id)
+   m_Id(id),m_FrameIdx(false),m_pSSMutex(new QMutex())
 {
    setObjectName("VideoRenderer:"+id);
 }
@@ -71,7 +73,7 @@ VideoRenderer::~VideoRenderer()
 }
 
 ///Get the data from shared memory and transform it into a QByteArray
-bool VideoRenderer::renderToBitmap(QByteArray& data)
+bool VideoRenderer::renderToBitmap()
 {
 #ifdef Q_OS_LINUX
    if (!m_isRendering) {
@@ -86,7 +88,10 @@ bool VideoRenderer::renderToBitmap(QByteArray& data)
    while (m_BufferGen == m_pShmArea->m_BufferGen) {
       shmUnlock();
       const struct timespec timeout = createTimeout();
+      if(!VideoModel::instance()->startStopMutex()->tryLock())
+         return false;
       int err = sem_timedwait(&m_pShmArea->notification, &timeout);
+      VideoModel::instance()->startStopMutex()->unlock();
       // Useful for debugging
 //       switch (errno ) {
 //          case EINTR:
@@ -124,15 +129,17 @@ bool VideoRenderer::renderToBitmap(QByteArray& data)
       return false;
    }
 
-   if (data.size() != m_pShmArea->m_BufferSize)
-      data.resize(m_pShmArea->m_BufferSize);
-   memcpy(data.data(),m_pShmArea->m_Data,m_pShmArea->m_BufferSize);
+   bool otherFrame = ! m_FrameIdx;
+   if (m_Frame[otherFrame].size() != m_pShmArea->m_BufferSize)
+      m_Frame[otherFrame].resize(m_pShmArea->m_BufferSize);
+   memcpy(m_Frame[otherFrame].data(),m_pShmArea->m_Data,m_pShmArea->m_BufferSize);
    m_BufferGen = m_pShmArea->m_BufferGen;
    shmUnlock();
+   m_FrameIdx = !m_FrameIdx;
 //    return data;
+//    m_pSSMutex->unlock();
    return true;
 #else
-   Q_UNUSED(data)
    return false;
 #endif
 }
@@ -254,10 +261,9 @@ timespec VideoRenderer::createTimeout()
 ///Update the buffer
 void VideoRenderer::timedEvents()
 {
-   m_pMutex->lock();
 
-   bool ok = renderToBitmap(m_Frame);
-   m_pMutex->unlock();
+   bool ok = renderToBitmap();
+
    if (ok == true) {
       emit frameUpdated();
    }
@@ -270,20 +276,32 @@ void VideoRenderer::timedEvents()
 ///Start the rendering loop
 void VideoRenderer::startRendering()
 {
+   VideoModel::instance()->startStopMutex()->lock();
    QMutexLocker locker(m_pMutex);
    startShm();
    if (!m_pTimer) {
-      m_pTimer = new QTimer(this);
+      m_pTimer = new QTimer(nullptr);
+
+//       m_pTimer->moveToThread(thread());
       connect(m_pTimer,SIGNAL(timeout()),this,SLOT(timedEvents()));
-      m_pTimer->setInterval(42);
+      m_pTimer->setInterval(30);
    }
-   m_pTimer->start();
+
+   if (!m_pTimer->isActive()) {
+      qDebug() << "Is running" << thread()->isRunning();
+      m_pTimer->start();
+   }
+   else
+      qDebug() << "Timer already started!";
+
    m_isRendering = true;
+   VideoModel::instance()->startStopMutex()->unlock();
 }
 
 ///Stop the rendering loop
 void VideoRenderer::stopRendering()
 {
+   VideoModel::instance()->startStopMutex()->lock();
    QMutexLocker locker(m_pMutex);
    m_isRendering = false;
    qDebug() << "Stopping rendering on" << m_Id;
@@ -291,8 +309,7 @@ void VideoRenderer::stopRendering()
       m_pTimer->stop();
    emit stopped();
    stopShm();
-   //qDebug() << "Video stopped for call" << id;
-   //emit videoStopped();
+   VideoModel::instance()->startStopMutex()->unlock();
 }
 
 
@@ -305,7 +322,7 @@ void VideoRenderer::stopRendering()
 ///Get the raw bytes directly from the SHM, not recommended, but optimal
 const char* VideoRenderer::rawData()
 {
-   return m_isRendering?m_Frame.data():nullptr;
+   return m_isRendering?m_Frame[m_FrameIdx].data():nullptr;
 }
 
 ///Is this redenrer active
@@ -317,7 +334,7 @@ bool VideoRenderer::isRendering()
 ///Return the current framerate
 QByteArray VideoRenderer::currentFrame()
 {
-   return m_Frame;
+   return m_Frame[m_FrameIdx];
 }
 
 ///Return the current resolution
diff --git a/src/lib/videorenderer.h b/src/lib/videorenderer.h
index f18db3b..d07607a 100644
--- a/src/lib/videorenderer.h
+++ b/src/lib/videorenderer.h
@@ -70,9 +70,11 @@ class LIB_EXPORT VideoRenderer : public QObject {
       uint       m_BufferGen  ;
       bool       m_isRendering;
       QTimer*    m_pTimer     ;
-      QByteArray m_Frame      ;
+      QByteArray m_Frame[2]   ;
+      bool       m_FrameIdx   ;
       Resolution m_Res        ;
       QMutex*    m_pMutex     ;
+      QMutex*    m_pSSMutex   ;
       QString    m_Id         ;
 
       //Constants
@@ -82,7 +84,7 @@ class LIB_EXPORT VideoRenderer : public QObject {
       timespec createTimeout();
       bool     shmLock      ();
       void     shmUnlock    ();
-      bool     renderToBitmap(QByteArray& data);
+      bool     renderToBitmap();
 
    private Q_SLOTS:
       void timedEvents();
diff --git a/src/widgets/videoglframe.cpp b/src/widgets/videoglframe.cpp
index 0354718..3f32a25 100644
--- a/src/widgets/videoglframe.cpp
+++ b/src/widgets/videoglframe.cpp
@@ -106,10 +106,9 @@ void ThreadedPainter2::copyFrame()
    if (m_pRenderer) {
       m_pRenderer->mutex()->lock();
       const QByteArray raw = m_pRenderer->currentFrame();
-      if (m_Data)
-         free(m_Data);
-      m_Data = (char*)malloc(raw.size()*sizeof(char));
-      memcpy(m_Data,raw.data(),raw.size());
+      if (!m_Data)
+         m_Data = (char*)malloc(raw.size()*sizeof(char));
+      m_Data = (char*)raw.data();
       m_ActiveSize = m_pRenderer->activeResolution();
       m_pRenderer->mutex()->unlock();
       emit changed();
@@ -120,8 +119,6 @@ void ThreadedPainter2::draw(QPainter* p)
 {
    Q_UNUSED(p)
    if (m_pRenderer && isRendering) {
-//       QMutexLocker locker(&mutex);
-//       m_pRenderer->mutex()->lock();
 
       // save the GL state set for QPainter
       saveGLState();
@@ -181,12 +178,6 @@ void ThreadedPainter2::draw(QPainter* p)
      m_pPainter(new ThreadedPainter2(this,parent)),
      m_pRenderer(nullptr)
  {
-
-//    Should work, does not
-//    QThread* t = new QThread(this);
-//    connect(t, SIGNAL(started()), m_pPainter, SLOT(rendererStarted()));
-//    m_pPainter->moveToThread(t);
-//    t->start();
    connect(m_pPainter,SIGNAL(changed()),this,SLOT(slotEmitChanged()));
 
    m_pPainter->tile_list = glGenLists(1);


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic