Skip to content
Snippets Groups Projects
Select Git revision
  • 727dbc99b554dc8ea143b465044ac3b64e11c565
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/201911
  • release/releaseWindowsTestOne
  • release/releaseTest
  • release/releaseWindowsTest
  • release/windowsReleaseTest
  • release/201910
  • release/qt/201910
  • release/windows-test/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • 1.0.0
  • 0.3.0
  • 0.2.1
  • 0.2.0
  • 0.1.0
26 results

videomodel.cpp

  • user avatar
    Emmanuel Lepage Vallee authored
    727dbc99
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    videomodel.cpp 7.06 KiB
    /****************************************************************************
     *   Copyright (C) 2012-2014 by Savoir-Faire Linux                          *
     *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
     *                                                                          *
     *   This library is free software; you can redistribute it and/or          *
     *   modify it under the terms of the GNU Lesser General Public             *
     *   License as published by the Free Software Foundation; either           *
     *   version 2.1 of the License, or (at your option) any later version.     *
     *                                                                          *
     *   This library is distributed in the hope that it will be useful,        *
     *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
     *   Lesser General Public License for more details.                        *
     *                                                                          *
     *   You should have received a copy of the GNU General Public License      *
     *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
     ***************************************************************************/
    #include "videomodel.h"
    
    //Qt
    #include <QtCore/QMutex>
    
    //SFLPhone
    #include "dbus/videomanager.h"
    #include "videodevice.h"
    #include "call.h"
    #include "callmodel.h"
    #include "videorenderer.h"
    
    //Static member
    VideoModel* VideoModel::m_spInstance = nullptr;
    
    ///Constructor
    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())                           );
       connect( &interface , SIGNAL(startedDecoding(QString,QString,int,int)), this, SLOT(startedDecoding(QString,QString,int,int)));
       connect( &interface , SIGNAL(stoppedDecoding(QString,QString))        , this, SLOT(stoppedDecoding(QString,QString))        );
    }
    
    
    VideoModel::~VideoModel()
    {
       foreach(VideoDevice* dev, m_hDevices) {
          delete dev;
       }
       m_hDevices.clear();
    }
    
    ///Singleton
    VideoModel* VideoModel::instance()
    {
       if (!m_spInstance) {
          m_spInstance = new VideoModel();
       }
       return m_spInstance;
    }
    
    ///Return the call renderer or nullptr
    VideoRenderer* VideoModel::getRenderer(const Call* call) const
    {
       if (!call) return nullptr;
       return m_lRenderers[call->id()];
    }
    
    ///Get the video preview renderer
    VideoRenderer* VideoModel::previewRenderer()
    {
       if (!m_lRenderers["local"]) {
          VideoInterface& interface = DBus::VideoManager::instance();
          m_lRenderers["local"] = new VideoRenderer("local","", Resolution(interface.getActiveDeviceSize()));
       }
       return m_lRenderers["local"];
    }
    
    ///Stop video preview
    void VideoModel::stopPreview()
    {
       VideoInterface& interface = DBus::VideoManager::instance();
       interface.stopCamera();
       m_PreviewState = false;
    }
    
    ///Start video preview
    void VideoModel::startPreview()
    {
       if (m_PreviewState) return;
       VideoInterface& interface = DBus::VideoManager::instance();
       interface.startCamera();
       m_PreviewState = true;
    }
    
    ///Is the video model fetching preview from a camera
    bool VideoModel::isPreviewing()
    {
       return m_PreviewState;
    }
    
    ///@todo Set the video buffer size
    void VideoModel::setBufferSize(uint size)
    {
       m_BufferSize = size;
    }
    
    ///Event callback
    void VideoModel::deviceEvent()
    {
       
    }
    
    ///A video is not being rendered
    void VideoModel::startedDecoding(const QString& id, const QString& shmPath, int width, int height)
    {
       Q_UNUSED(id)
    
       if (m_lRenderers[id] == nullptr ) {
          m_lRenderers[id] = new VideoRenderer(id,shmPath,Resolution(width,height));
          m_lRenderers[id]->moveToThread(this);
          if (!isRunning())
             start();
       }
       else {
          VideoRenderer* renderer = m_lRenderers[id];
          renderer->setShmPath(shmPath);
          renderer->setResolution(QSize(width,height));
       }
    
       m_lRenderers[id]->startRendering();
       VideoDevice* dev = device(id);
       if (dev) {
          emit dev->renderingStarted(m_lRenderers[id]);
       }
       if (id != "local") {
          qDebug() << "Starting video for call" << id;
          emit videoCallInitiated(m_lRenderers[id]);
       }
       else {
          m_PreviewState = true;
          emit previewStateChanged(true);
          emit previewStarted(m_lRenderers[id]);
       }
    }
    
    ///A video stopped being rendered
    void VideoModel::stoppedDecoding(const QString& id, const QString& shmPath)
    {
       Q_UNUSED(shmPath)
       VideoRenderer* r = m_lRenderers[id];
       if ( r ) {
          r->stopRendering();
       }
       qDebug() << "Video stopped for call" << id <<  "Renderer found:" << (m_lRenderers[id] != nullptr);
    //    emit videoStopped();
       
       VideoDevice* dev = device(id);
       if (dev) {
          emit dev->renderingStopped(r);
       }
       if (id == "local") {
          m_PreviewState = false;
          emit previewStateChanged(false);
          emit previewStopped(r);
       }
    //    r->mutex()->lock();
       m_lRenderers[id] = nullptr;
       delete r;
    }
    
    // void VideoModel::run()
    // {
    //    exec();
    // }
    
    
    // void VideoModel::setActiveDevice(const VideoDevice* device)
    // {
    //    VideoInterface& interface = DBus::VideoManager::instance();
    //    if (isPreviewing()) {
    //       switchDevice(device);
    //    }
    //    interface.setActiveDevice(device->id());
    // }
    
    void VideoModel::switchDevice(const VideoDevice* device) const
    {
       VideoInterface& interface = DBus::VideoManager::instance();
       interface.switchInput(device->id());
    }
    
    QList<VideoDevice*> VideoModel::devices()
    {
       QHash<QString,VideoDevice*> devicesHash;
       VideoInterface& interface = DBus::VideoManager::instance();
       const QStringList deviceList = interface.getDeviceList();
       if (deviceList.size() == m_hDevices.size()) {
    //       qDebug() << "\n\nRETUNING CACHE" << m_hDevices.values();
    //       foreach(const QString& deviceName,deviceList) {
    //          qDebug() << "Meh" << m_hDevices[deviceName];
    //       }
          return m_hDevices.values();
       }
    
       foreach(const QString& deviceName,deviceList) {
          if (!m_hDevices[deviceName]) {
             devicesHash[deviceName] = new VideoDevice(deviceName);
    //          qDebug() << "\n\nNEW" << devicesHash[deviceName];
          }
          else {
    //          qDebug() << "\n\nPUSH" << m_hDevices[deviceName];
             devicesHash[deviceName] = m_hDevices[deviceName];
          }
       }
       foreach(VideoDevice* dev,m_hDevices) {
          if (dev && devicesHash.key(dev).isEmpty()) {
    //          qDebug() << "\n\nDELETE";
             delete dev;
          }
       }
       m_hDevices.clear();
       m_hDevices = devicesHash;
       return m_hDevices.values();
    }
    
    // VideoDevice* VideoModel::activeDevice() const
    // {
    //    VideoInterface& interface = DBus::VideoManager::instance();
    //    const QString deId = interface.getActiveDevice();
    //    if (!deId.isEmpty() && !m_hDevices.size()) {
    //       const_cast<VideoModel*>(this)->devices();
    //    }
    //    return m_hDevices[deId];
    // }
    
    VideoDevice* VideoModel::device(const QString &id)
    {
       return m_hDevices[id];
    }
    
    QMutex* VideoModel::startStopMutex() const
    {
       return m_SSMutex;
    }