diff --git a/daemon/src/video/test/make_rtp_stream.sh b/daemon/src/video/test/make_rtp_stream.sh index 37a005bdb2103566efa80bdc16dc1fd73b3de67e..dfb4759b5bde85a8fce02915beb7642754a51eb8 100755 --- a/daemon/src/video/test/make_rtp_stream.sh +++ b/daemon/src/video/test/make_rtp_stream.sh @@ -1,2 +1,2 @@ # disables audio -ffmpeg -f video4linux2 -i /dev/video0 -srcw 320 -srch 240 -an -r 30 -vprofile baseline -level 13 -vb 400000 -vcodec libx264 -payload_type 109 -preset veryfast -tune zerolatency -f rtp rtp://127.0.0.1:2228 +ffmpeg -f video4linux2 -i /dev/video0 -srcw 320 -srch 240 -an -r 30 -vprofile baseline -level 13 -vb 400000 -vcodec libx264 -payload_type 109 -preset veryfast -tune zerolatency -f rtp rtp://192.168.50.116:2228 diff --git a/kde/src/CMakeLists.txt b/kde/src/CMakeLists.txt index 23261055f70c72b7d25780291889cb6d7f451b6f..6193215c6c6c5e75032d903d56cfdeb44b9f967b 100755 --- a/kde/src/CMakeLists.txt +++ b/kde/src/CMakeLists.txt @@ -55,7 +55,7 @@ SET( widgets/CategorizedTreeWidget.cpp widgets/VideoDock.cpp widgets/VideoWidget.cpp - widgets/AcceleratedVideoWidget.cpp +# widgets/AcceleratedVideoWidget.cpp Codec.cpp CallView.cpp ) diff --git a/kde/src/CallView.cpp b/kde/src/CallView.cpp index ad0ca32bc476846e706332bd8642e9e6758dcc7b..415cb98d175f28b3a0bfd500b3686b3e76881310 100644 --- a/kde/src/CallView.cpp +++ b/kde/src/CallView.cpp @@ -318,7 +318,7 @@ bool CallView::contactToCall(QTreeWidgetItem *parent, int index, const QMimeData Contact* contact = AkonadiBackend::getInstance()->getContactByUid(encodedContact); if (contact) { Call* call2 = NULL; - if (!SFLPhone::app()->view()->selectCallPhoneNumber(call2,contact)) + if (!SFLPhone::app()->view()->selectCallPhoneNumber(&call2,contact)) return false; if (!parent) { //Dropped on free space @@ -331,6 +331,14 @@ bool CallView::contactToCall(QTreeWidgetItem *parent, int index, const QMimeData } else { //Dropped on call +// if (!call2) { +// call2 = SFLPhone::model()->addDialingCall(contact->getFormattedName()); +// } +// QByteArray encodedPhoneNumber = data->data( MIME_PHONENUMBER ); +// if (!encodedPhoneNumber.isEmpty()) { +// call2->setCallNumber(encodedPhoneNumber); +// } + call2->actionPerformed(CALL_ACTION_ACCEPT); int state = SFLPhone::model()->getCall(parent)->getState(); if(state == CALL_STATE_INCOMING || state == CALL_STATE_DIALING || state == CALL_STATE_TRANSFER || state == CALL_STATE_TRANSF_HOLD) { diff --git a/kde/src/SFLPhone.cpp b/kde/src/SFLPhone.cpp index 366f31abfae50f9538c6d07b33c53d95dbf379be..14113f29bff8d987aefeed64f104512b2300cca9 100755 --- a/kde/src/SFLPhone.cpp +++ b/kde/src/SFLPhone.cpp @@ -521,12 +521,6 @@ void SFLPhone::displayVideoDock(const QString& callId) Q_UNUSED(callId) if (!m_pVideoDW) { m_pVideoDW = new VideoDock(this); -// QWidget* wdg = new QWidget(m_pVideoDW); -// VideoWidget* vwdg = new VideoWidget(m_pVideoDW); -// QVBoxLayout* l = new QVBoxLayout(wdg); -// l->addWidget(vwdg); -// l->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding)); -// m_pVideoDW->setWidget(wdg); } m_pVideoDW->show(); } diff --git a/kde/src/SFLPhoneView.cpp b/kde/src/SFLPhoneView.cpp index f8a9ec82af51e0614e9c9882a1f1d3f4dd2bc1a1..bb1b22059097dbb4158cf9ffa3ab8b79682cca8d 100755 --- a/kde/src/SFLPhoneView.cpp +++ b/kde/src/SFLPhoneView.cpp @@ -215,12 +215,12 @@ void SFLPhoneView::typeString(QString str) Call* currentCall = nullptr; Call* candidate = nullptr; - if(call && (call->getState() == CALL_STATE_CURRENT || call->getState() == CALL_STATE_RECORD)) { + if(call && call->getState() == CALL_STATE_CURRENT) { currentCall = call; } foreach (Call* call2, SFLPhone::model()->getCallList()) { - if(dynamic_cast<Call*>(call2) && currentCall != call2 && (call2->getState() == CALL_STATE_CURRENT || call->getState() == CALL_STATE_RECORD)) { + if(dynamic_cast<Call*>(call2) && currentCall != call2 && call2->getState() == CALL_STATE_CURRENT) { action(call2, CALL_ACTION_HOLD); } else if(dynamic_cast<Call*>(call2) && call2->getState() == CALL_STATE_DIALING) { @@ -334,12 +334,12 @@ void SFLPhoneView::action(Call* call, call_action action) } //action ///Select a phone number when calling using a contact -bool SFLPhoneView::selectCallPhoneNumber(Call* call2,Contact* contact) +bool SFLPhoneView::selectCallPhoneNumber(Call** call2,Contact* contact) { if (contact->getPhoneNumbers().count() == 1) { - call2 = SFLPhone::model()->addDialingCall(contact->getFormattedName(),AccountList::getCurrentAccount()); - if (call2) - call2->appendText(contact->getPhoneNumbers()[0]->getNumber()); + *call2 = SFLPhone::model()->addDialingCall(contact->getFormattedName(),AccountList::getCurrentAccount()); + if (*call2) + (*call2)->appendText(contact->getPhoneNumbers()[0]->getNumber()); } else if (contact->getPhoneNumbers().count() > 1) { bool ok = false; @@ -351,9 +351,9 @@ bool SFLPhoneView::selectCallPhoneNumber(Call* call2,Contact* contact) } QString result = QInputDialog::getItem (this, i18n("Select phone number"), i18n("This contact have many phone number, please select the one you wish to call"), list, 0, false, &ok); if (ok) { - call2 = SFLPhone::model()->addDialingCall(contact->getFormattedName(), AccountList::getCurrentAccount()); - if (call2) - call2->appendText(map[result]); + (*call2) = SFLPhone::model()->addDialingCall(contact->getFormattedName(), AccountList::getCurrentAccount()); + if (*call2) + (*call2)->appendText(map[result]); } else { kDebug() << "Operation cancelled"; @@ -423,10 +423,6 @@ void SFLPhoneView::updateWindowCallState() buttonIconFiles [ SFLPhone::Record ] = ICON_REC_DEL_ON ; m_pMessageBoxW->setVisible(true && ConfigurationSkeleton::displayMessageBox()); break; - case CALL_STATE_RECORD: - buttonIconFiles [ SFLPhone::Record ] = ICON_REC_DEL_ON ; - m_pMessageBoxW->setVisible(true && ConfigurationSkeleton::displayMessageBox()); - break; case CALL_STATE_DIALING: enabledActions [ SFLPhone::Hold ] = false ; enabledActions [ SFLPhone::Transfer ] = false ; @@ -630,7 +626,6 @@ void SFLPhoneView::displayMessageBox(bool checked) && call && (call->getState() == CALL_STATE_CURRENT || call->getState() == CALL_STATE_HOLD - || call->getState() == CALL_STATE_RECORD ) ); } @@ -774,7 +769,7 @@ void SFLPhoneView::accept() } else { int state = call->getState(); - if(state == CALL_STATE_RINGING || state == CALL_STATE_CURRENT || state == CALL_STATE_HOLD || state == CALL_STATE_BUSY || state == CALL_STATE_RECORD) + if (state == CALL_STATE_RINGING || state == CALL_STATE_CURRENT || state == CALL_STATE_HOLD || state == CALL_STATE_BUSY) { kDebug() << "Calling when item currently ringing, current, hold or busy. Opening an item."; SFLPhone::model()->addDialingCall(); diff --git a/kde/src/SFLPhoneView.h b/kde/src/SFLPhoneView.h index f2c4a4081094739b3904031f684522f285aba376..8755af06ea51695a7a4a25217fa6aa7ede4849aa 100755 --- a/kde/src/SFLPhoneView.h +++ b/kde/src/SFLPhoneView.h @@ -80,7 +80,7 @@ public: QErrorMessage * getErrorWindow(); - bool selectCallPhoneNumber(Call* call,Contact* contact); + bool selectCallPhoneNumber(Call** call,Contact* contact); private slots: /** diff --git a/kde/src/lib/CMakeLists.txt b/kde/src/lib/CMakeLists.txt index 6f6348727dd9f36dd8131bfd98a08ece6eec6f15..fc2b709d0d19b9d9b613dfcc440f9625f881e71e 100644 --- a/kde/src/lib/CMakeLists.txt +++ b/kde/src/lib/CMakeLists.txt @@ -35,6 +35,7 @@ set( qtsflphone_LIB_SRCS ContactBackend.cpp VideoCodec.cpp VideoModel.cpp + VideoRenderer.cpp VideoDevice.cpp CredentialModel.cpp AudioCodecModel.cpp @@ -128,6 +129,7 @@ set( qtsflphone_LIB_HDRS VideoCodec.h VideoModel.h VideoDevice.h + VideoRenderer.h CredentialModel.h AudioCodecModel.h configurationmanager_interface_singleton.h diff --git a/kde/src/lib/Call.cpp b/kde/src/lib/Call.cpp index 21e7046596b13d339e7bbf30bdeeacf1182066ab..f4743ba9609adbbffdf502ee65045d609cc6f2b9 100644 --- a/kde/src/lib/Call.cpp +++ b/kde/src/lib/Call.cpp @@ -46,7 +46,6 @@ const call_state Call::actionPerformedStateMap [14][5] = /*ERROR */ {CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR },/**/ /*CONF */ {CALL_STATE_ERROR , CALL_STATE_CURRENT , CALL_STATE_TRANSFER , CALL_STATE_CURRENT , CALL_STATE_CURRENT },/**/ /*CONF_HOLD */ {CALL_STATE_ERROR , CALL_STATE_HOLD , CALL_STATE_TRANSF_HOLD , CALL_STATE_HOLD , CALL_STATE_HOLD },/**/ -/*RECORD */ {CALL_STATE_ERROR , CALL_STATE_CURRENT , CALL_STATE_TRANSFER , CALL_STATE_CURRENT , CALL_STATE_CURRENT },/**/ };// @@ -66,7 +65,6 @@ const function Call::actionPerformedFunctionMap[14][5] = /*ERROR */ {&Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing },/**/ /*CONF */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::hold , &Call::setRecord },/**/ /*CONF_HOLD */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::unhold , &Call::setRecord },/**/ -/*RECORD */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::hold , &Call::setRecord },/**/ };// @@ -86,7 +84,6 @@ const call_state Call::stateChangedStateMap [14][6] = /*ERROR */ {CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR },/**/ /*CONF */ {CALL_STATE_CURRENT , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/ /*CONF_HOLD */ {CALL_STATE_HOLD , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/ -/*RECORD */ {CALL_STATE_CURRENT , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/ };// const function Call::stateChangedFunctionMap[14][6] = @@ -105,7 +102,6 @@ const function Call::stateChangedFunctionMap[14][6] = /*ERROR */ {&Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing , &Call::stop , &Call::nothing },/**/ /*CONF */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },/**/ /*CONF_HOLD */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },/**/ -/*RECORD */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },/**/ };// const char * Call::historyIcons[3] = {ICON_HISTORY_INCOMING, ICON_HISTORY_OUTGOING, ICON_HISTORY_MISSED}; @@ -286,8 +282,6 @@ call_state Call::getStartStateFromDaemonCallState(QString daemonCallState, QStri return CALL_STATE_RINGING ; else if(daemonCallState == DAEMON_CALL_STATE_INIT_INCOMING ) return CALL_STATE_INCOMING ; - else if(daemonCallState == DAEMON_CALL_STATE_INIT_RECORD ) - return CALL_STATE_RECORD ; else if(daemonCallState == DAEMON_CALL_STATE_INIT_RINGING ) return CALL_STATE_RINGING ; else @@ -309,16 +303,10 @@ daemon_call_state Call::toDaemonCallState(const QString& stateName) return DAEMON_CALL_STATE_RINGING ; if(stateName == QString(CALL_STATE_CHANGE_CURRENT) ) return DAEMON_CALL_STATE_CURRENT ; - if(stateName == QString(CALL_STATE_CHANGE_RECORD) ) - return DAEMON_CALL_STATE_RECORD ; if(stateName == QString(CALL_STATE_CHANGE_UNHOLD_CURRENT) ) return DAEMON_CALL_STATE_CURRENT ; - if(stateName == QString(CALL_STATE_CHANGE_UNHOLD_RECORD) ) - return DAEMON_CALL_STATE_CURRENT ; if(stateName == QString(CALL_STATE_CHANGE_HOLD) ) return DAEMON_CALL_STATE_HOLD ; - if(stateName == QString(CALL_STATE_RECORD) ) - return DAEMON_CALL_STATE_RECORD ; if(stateName == QString(CALL_STATE_CHANGE_BUSY) ) return DAEMON_CALL_STATE_BUSY ; if(stateName == QString(CALL_STATE_CHANGE_FAILURE) ) @@ -380,8 +368,6 @@ const QString Call::toHumanStateName() const break; case CALL_STATE_CONFERENCE_HOLD: return ( "Conference (hold)" ); - case CALL_STATE_RECORD: - return ( "Recording" ); default: return ""; } diff --git a/kde/src/lib/CallModel.cpp b/kde/src/lib/CallModel.cpp index 82aa56f48d01afe0afb6274477a4c2ae9d23e34e..44a89692c6aee71a574aad4c05afc5fa2ce352ff 100644 --- a/kde/src/lib/CallModel.cpp +++ b/kde/src/lib/CallModel.cpp @@ -20,7 +20,8 @@ //Parent #include <CallModel.h> -#include <HistoryModel.h> +#include "video_interface_singleton.h" +#include "HistoryModel.h" bool CallModelBase::dbusInit = false; CallMap CallModelBase::m_sActiveCalls; @@ -30,9 +31,10 @@ CallModelBase::CallModelBase(QObject* parent) : QObject(parent) { if (!dbusInit) { CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance(); + VideoInterface& interface = VideoInterfaceSingleton::getInstance(); //SLOTS - // SENDER SIGNAL RECEIVER SLOT / + /* SENDER SIGNAL RECEIVER SLOT */ /**/connect(&callManager, SIGNAL( callStateChanged (const QString &, const QString & ) ), this , SLOT( callStateChanged ( const QString &, const QString & ) ) ); /**/connect(&callManager, SIGNAL( incomingCall (const QString &, const QString &, const QString & ) ), this , SLOT( incomingCall ( const QString &, const QString & ) ) ); /**/connect(&callManager, SIGNAL( conferenceCreated (const QString & ) ), this , SLOT( incomingConference ( const QString & ) ) ); @@ -40,6 +42,8 @@ CallModelBase::CallModelBase(QObject* parent) : QObject(parent) /**/connect(&callManager, SIGNAL( conferenceRemoved (const QString & ) ), this , SLOT( conferenceRemovedSlot ( const QString & ) ) ); /**/connect(&callManager, SIGNAL( voiceMailNotify (const QString &, int ) ), this , SLOT( voiceMailNotifySlot ( const QString &, int ) ) ); /**/connect(&callManager, SIGNAL( volumeChanged (const QString &, double ) ), this , SLOT( volumeChangedSlot ( const QString &, double ) ) ); + /**/connect(&interface , SIGNAL( startedDecoding (QString,QString,int,int ) ), this, SLOT( startedDecoding ( const QString &, const QString & ) ) ); + /**/connect(&interface , SIGNAL( stoppedDecoding (QString,QString ) ), this, SLOT( stoppedDecoding ( const QString &, const QString & ) ) ); /* */ connect(HistoryModel::self(),SIGNAL(newHistoryCall(Call*)),this,SLOT(addPrivateCall(Call*))); @@ -174,6 +178,23 @@ void CallModelBase::removeActiveCall(Call* call) //m_sActiveCalls[call->getCallId()] = nullptr; } +///Updating call state when video is added +void CallModelBase::startedDecoding(const QString& callId, const QString& shmKey ) +{ + Call* call = getCall(callId); + if (call) { + + } +} + +///Updating call state when video is removed +void CallModelBase::stoppedDecoding(const QString& callId, const QString& shmKey) +{ + Call* call = getCall(callId); + if (call) { + + } +} /***************************************************************************** * * diff --git a/kde/src/lib/CallModel.h b/kde/src/lib/CallModel.h index 131c9f06040f2356d208e8dbf149cc444c3e40ea..a4711570ed57ad57692271f35c10c673d451e33e 100644 --- a/kde/src/lib/CallModel.h +++ b/kde/src/lib/CallModel.h @@ -65,6 +65,10 @@ private slots: void conferenceRemovedSlot ( const QString& confId ); void voiceMailNotifySlot ( const QString& accountID , int count ); void volumeChangedSlot ( const QString& device , double value ); + void removeActiveCall ( Call* call ); + void addPrivateCall ( Call* call ); + void startedDecoding ( const QString& callId , const QString& shmKey ); + void stoppedDecoding ( const QString& callId , const QString& shmKey ); protected: virtual Call* findCallByCallId ( const QString& callId ) = 0; @@ -77,9 +81,6 @@ protected: //Attributes static CallMap m_sActiveCalls; -private slots: - void removeActiveCall(Call*); - void addPrivateCall(Call* call); private: static bool dbusInit; diff --git a/kde/src/lib/VideoDevice.h b/kde/src/lib/VideoDevice.h index 18322baf556ed1c9fb5c1f762de3304071dab699..e34573137151060aeccb281e77f1dd8359959139 100644 --- a/kde/src/lib/VideoDevice.h +++ b/kde/src/lib/VideoDevice.h @@ -21,6 +21,7 @@ #include "typedefs.h" #include <QStringList> +#include <QtCore/QSize> ///@typedef VideoChannel A channel available in a Device typedef QString VideoChannel; @@ -38,6 +39,8 @@ struct LIB_EXPORT Resolution { height=size.split("x")[1].toInt(); } } + Resolution(const Resolution& res):width(res.width),height(res.height){} + Resolution(const QSize& size):width(size.width()),height(size.height()){} //Getter QString toString() { return QString::number(width)+"x"+QString::number(height);} diff --git a/kde/src/lib/VideoModel.cpp b/kde/src/lib/VideoModel.cpp index 6a6a44a577dc4e87119296602bd4b87665cbc3b8..1aed38cdfa8d5437d5044e2d04caa9f9f6f160a8 100644 --- a/kde/src/lib/VideoModel.cpp +++ b/kde/src/lib/VideoModel.cpp @@ -19,248 +19,26 @@ #include "VideoModel.h" //Posix -#include <sys/ipc.h> -#include <sys/sem.h> -#include <sys/shm.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/mman.h> -#include <semaphore.h> +// #include <sys/ipc.h> +// #include <sys/sem.h> +// #include <sys/shm.h> +// #include <fcntl.h> +// #include <unistd.h> +// #include <sys/mman.h> +// #include <semaphore.h> //SFLPhone #include "video_interface_singleton.h" #include "VideoDevice.h" #include "Call.h" #include "CallModel.h" +#include "VideoRenderer.h" //Static member VideoModel* VideoModel::m_spInstance = NULL; -///Shared memory object -struct SHMHeader { - sem_t notification; - sem_t mutex; - - unsigned m_BufferGen; - int m_BufferSize; - - char m_Data[0]; -}; - - -///Manage shared memory and convert it to QByteArray -class VideoRenderer { - //This class is private there is no point to make accessors - friend class VideoModel; - - private: - //Attributes - uint m_Width ; - uint m_Height ; - QString m_ShmPath ; - int fd ; - SHMHeader* m_pShmArea ; - signed int m_ShmAreaLen ; - uint m_BufferGen ; - bool m_isRendering; - - //Constants - static const int TIMEOUT_SEC = 1; // 1 second - - //Helpers - timespec createTimeout(); - bool shmLock (); - void shmUnlock (); - - - public: - //Constructor - VideoRenderer (); - ~VideoRenderer(); - - //Mutators - bool resizeShm(); - void stopShm (); - bool startShm (); - - //Getters - QByteArray renderToBitmap(QByteArray& data, bool& ok); -}; - -///Constructor -VideoRenderer::VideoRenderer(): - m_Width(0), m_Height(0), m_ShmPath(QString()), fd(-1), - m_pShmArea((SHMHeader*)MAP_FAILED), m_ShmAreaLen(0), m_BufferGen(0), - m_isRendering(false) -{ - -} - -///Destructor -VideoRenderer::~VideoRenderer() -{ - stopShm(); - delete m_pShmArea; -} - -///Get the data from shared memory and transform it into a QByteArray -QByteArray VideoRenderer::renderToBitmap(QByteArray& data,bool& ok) -{ - if (!m_isRendering) { - return QByteArray(); - } - - if (!shmLock()) { - ok = false; - return QByteArray(); - } - - // wait for a new buffer - while (m_BufferGen == m_pShmArea->m_BufferGen) { - shmUnlock(); - const struct timespec timeout = createTimeout(); - int err = sem_timedwait(&m_pShmArea->notification, &timeout); - // Could not decrement semaphore in time, returning -// switch (errno ) { -// case EINTR: -// qDebug() << "Unlock failed: Interrupted function call (POSIX.1); see signal(7)"; -// ok = false; -// return QByteArray(); -// break; -// case EINVAL: -// qDebug() << "Unlock failed: Invalid argument (POSIX.1)"; -// ok = false; -// return QByteArray(); -// break; -// case EAGAIN: -// qDebug() << "Unlock failed: Resource temporarily unavailable (may be the same value as EWOULDBLOCK) (POSIX.1)"; -// ok = false; -// return QByteArray(); -// break; -// case ETIMEDOUT: -// qDebug() << "Unlock failed: Connection timed out (POSIX.1)"; -// ok = false; -// return QByteArray(); -// break; -// } - if (err < 0) { - ok = false; - return QByteArray(); - } - - if (!shmLock()) { - ok = false; - return QByteArray(); - } - } - - if (!resizeShm()) { - qDebug() << "Could not resize shared memory"; - ok = false; - return QByteArray(); - } - - if (data.size() != m_pShmArea->m_BufferSize) - data.resize(m_pShmArea->m_BufferSize); - memcpy(data.data(),m_pShmArea->m_Data,m_pShmArea->m_BufferSize); - m_BufferGen = m_pShmArea->m_BufferGen; - shmUnlock(); - return data; -} - -///Connect to the shared memory -bool VideoRenderer::startShm() -{ - if (fd != -1) { - qDebug() << "fd must be -1"; - return false; - } - - fd = shm_open(m_ShmPath.toAscii(), O_RDWR, 0); - if (fd < 0) { - qDebug() << "could not open shm area \"%s\", shm_open failed:%s" << m_ShmPath << strerror(errno); - return false; - } - m_ShmAreaLen = sizeof(SHMHeader); - m_pShmArea = (SHMHeader*) mmap(NULL, m_ShmAreaLen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (m_pShmArea == MAP_FAILED) { - qDebug() << "Could not map shm area, mmap failed"; - return false; - } - return true; -} - -///Disconnect from the shared memory -void VideoRenderer::stopShm() -{ - if (fd >= 0) - close(fd); - fd = -1; - - if (m_pShmArea != MAP_FAILED) - munmap(m_pShmArea, m_ShmAreaLen); - m_ShmAreaLen = 0; - m_pShmArea = (SHMHeader*) MAP_FAILED; -} - -///Resize the shared memory -bool VideoRenderer::resizeShm() -{ - while ((sizeof(SHMHeader) + m_pShmArea->m_BufferSize) > m_ShmAreaLen) { - const size_t new_size = sizeof(SHMHeader) + m_pShmArea->m_BufferSize; - - shmUnlock(); - if (munmap(m_pShmArea, m_ShmAreaLen)) { - qDebug() << "Could not unmap shared area:%s" << strerror(errno); - return false; - } - - m_pShmArea = (SHMHeader*) mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - m_ShmAreaLen = new_size; - - if (!m_pShmArea) { - m_pShmArea = 0; - qDebug() << "Could not remap shared area"; - return false; - } - - m_ShmAreaLen = new_size; - if (!shmLock()) - return false; - } - return true; -} - -///Lock the memory while the copy is being made -bool VideoRenderer::shmLock() -{ - const timespec timeout = createTimeout(); - /* We need an upper limit on how long we'll wait to avoid locking the whole GUI */ - if (sem_timedwait(&m_pShmArea->mutex, &timeout) == ETIMEDOUT) { - qDebug() << "Timed out before shm lock was acquired"; - return false; - } - return true; -} - -///Remove the lock, allow a new frame to be drawn -void VideoRenderer::shmUnlock() -{ - sem_post(&m_pShmArea->mutex); -} - -///Create a SHM timeout -timespec VideoRenderer::createTimeout() -{ - timespec timeout = {0, 0}; - if (clock_gettime(CLOCK_REALTIME, &timeout) == -1) - qDebug() << "clock_gettime"; - timeout.tv_sec += TIMEOUT_SEC; - return timeout; -} - ///Constructor -VideoModel::VideoModel():m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_Res(0,0),m_pTimer(0),m_PreviewState(false),m_pRenderer(new VideoRenderer()) +VideoModel::VideoModel():m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false),m_pRenderer(nullptr) { VideoInterface& interface = VideoInterfaceSingleton::getInstance(); connect( &interface , SIGNAL(deviceEvent() ), this, SLOT( deviceEvent() )); @@ -283,8 +61,6 @@ void VideoModel::stopPreview() VideoInterface& interface = VideoInterfaceSingleton::getInstance(); interface.stopPreview(); m_PreviewState = false; -// if (m_pTimer) -// m_pTimer->stop(); } ///Start video preview @@ -314,51 +90,44 @@ void VideoModel::deviceEvent() } -///Update the buffer -void VideoModel::timedEvents() -{ - bool ok = true; - QByteArray ba; - m_pRenderer->renderToBitmap(m_Frame,ok); - if (ok == true) { - qDebug() << "Emit"; - emit frameUpdated(); - } - else { - qDebug() << "Frame dropped"; - usleep(rand()%100000); //Be sure it can come back in sync - } -} - -///Return the current framerate -QByteArray VideoModel::getCurrentFrame() -{ - return m_Frame; -} - ///Return the current resolution -Resolution VideoModel::getActiveResolution() -{ - return m_Res; -} +// Resolution VideoModel::getActiveResolution() +// { +// return m_Res; +// } ///A video is not being rendered void VideoModel::startedDecoding(QString id, QString shmPath, int width, int height) { Q_UNUSED(id) - m_pRenderer->m_ShmPath = shmPath; - m_Res.width = width ; - m_Res.height = height ; - m_pRenderer->m_Width = width ; - m_pRenderer->m_Height = height ; - m_pRenderer->m_isRendering = true; - m_pRenderer->startShm(); - if (!m_pTimer) { - m_pTimer = new QTimer(this); - connect(m_pTimer,SIGNAL(timeout()),this,SLOT(timedEvents())); - m_pTimer->setInterval(42); +// m_pRenderer->m_ShmPath = shmPath; +// m_Res.width = width ; +// m_Res.height = height ; +// m_pRenderer->m_Width = width ; +// m_pRenderer->m_Height = height ; +// m_pRenderer->m_isRendering = true; +// m_pRenderer->startShm(); + +// if (!m_pTimer) { +// m_pTimer = new QTimer(this); +// connect(m_pTimer,SIGNAL(timeout()),this,SLOT(timedEvents())); +// m_pTimer->setInterval(42); +// } +// m_pTimer->start(); + + if (m_lRenderers[id] == nullptr ) { + m_lRenderers[id] = new VideoRenderer(shmPath,Resolution(width,height)); + } + else { + VideoRenderer* renderer = m_lRenderers[id]; + renderer->setShmPath(shmPath); + renderer->setResolution(QSize(width,height)); } - m_pTimer->start(); + + if (!m_pRenderer) + m_pRenderer = m_lRenderers[id]; + + m_pRenderer->startRendering(); if (id != "local") { qDebug() << "Starting video for call" << id; emit videoCallInitiated(id); @@ -369,20 +138,12 @@ void VideoModel::startedDecoding(QString id, QString shmPath, int width, int hei void VideoModel::stoppedDecoding(QString id, QString shmPath) { Q_UNUSED(shmPath) - m_pRenderer->m_isRendering = false; - m_pRenderer->stopShm(); + if (m_pRenderer) + m_pRenderer->stopRendering(); +// m_pRenderer->m_isRendering = false; +// m_pRenderer->stopShm(); qDebug() << "Video stopped for call" << id; emit videoStopped(); - if (m_pTimer) - m_pTimer->stop(); -} - -char* VideoModel::rawData() -{ - return m_pRenderer->m_pShmArea->m_Data; -} - -bool VideoModel::isRendering() -{ - return m_pRenderer->m_isRendering; +// if (m_pTimer) +// m_pTimer->stop(); } \ No newline at end of file diff --git a/kde/src/lib/VideoModel.h b/kde/src/lib/VideoModel.h index 6d02d5515f316d3bcbad56367b3c19ce57c373b3..3b0e057e17471fa30bdff27425a76c98819271f6 100644 --- a/kde/src/lib/VideoModel.h +++ b/kde/src/lib/VideoModel.h @@ -23,8 +23,7 @@ #include <QtCore/QObject> //Qt -class QSharedMemory; -class QTimer; +#include <QtCore/QHash> //SFLPhone #include "VideoDevice.h" @@ -41,11 +40,8 @@ public: //Getters bool isPreviewing (); - QByteArray getCurrentFrame (); - Resolution getActiveResolution(); - char* rawData (); - bool isRendering (); - +// Resolution getActiveResolution(); + VideoRenderer* getRenderer() {return m_pRenderer;} //TODO remove //Setters void setBufferSize(uint size); @@ -64,11 +60,9 @@ private: uint m_ShmKey ; uint m_SemKey ; int m_SetSetId ; - Resolution m_Res ; - QByteArray m_Frame ; - QTimer* m_pTimer ; void* m_pBuffer ; VideoRenderer* m_pRenderer ; + QHash<QString,VideoRenderer*> m_lRenderers; public slots: void stopPreview (); @@ -78,7 +72,6 @@ private slots: void startedDecoding(QString id, QString shmPath, int width, int height); void stoppedDecoding(QString id, QString shmPath); void deviceEvent(); - void timedEvents(); signals: ///Emitted when a new frame is ready diff --git a/kde/src/lib/VideoRenderer.cpp b/kde/src/lib/VideoRenderer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a9398eaf2c0e20339f6a1a92e9941e615d5e4f5 --- /dev/null +++ b/kde/src/lib/VideoRenderer.cpp @@ -0,0 +1,312 @@ +/************************************************************************************ + * Copyright (C) 2012 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 Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***********************************************************************************/ +#include "VideoRenderer.h" + +#include <QtCore/QDebug> + +#include <sys/ipc.h> +#include <sys/sem.h> +#include <sys/shm.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> +#include <semaphore.h> + +#include <QtCore/QTimer> + +///Shared memory object +struct SHMHeader { + sem_t notification; + sem_t mutex; + + unsigned m_BufferGen; + int m_BufferSize; + + char m_Data[0]; +}; + +///Constructor +VideoRenderer::VideoRenderer(QString shmPath, Resolution res): QObject(0), + m_Width(0), m_Height(0), m_ShmPath(QString()), fd(-1), + m_pShmArea((SHMHeader*)MAP_FAILED), m_ShmAreaLen(0), m_BufferGen(0), + m_isRendering(false),m_pTimer(nullptr),m_Res(res) +{ + m_ShmPath = shmPath ; + m_Width = res.width ; + m_Height = res.height ; +} + +///Destructor +VideoRenderer::~VideoRenderer() +{ + stopShm(); + //delete m_pShmArea; +} + +///Get the data from shared memory and transform it into a QByteArray +QByteArray VideoRenderer::renderToBitmap(QByteArray& data,bool& ok) +{ + if (!m_isRendering) { + return QByteArray(); + } + + if (!shmLock()) { + ok = false; + return QByteArray(); + } + + // wait for a new buffer + while (m_BufferGen == m_pShmArea->m_BufferGen) { + shmUnlock(); + const struct timespec timeout = createTimeout(); + int err = sem_timedwait(&m_pShmArea->notification, &timeout); + // Useful for debugging +// switch (errno ) { +// case EINTR: +// qDebug() << "Unlock failed: Interrupted function call (POSIX.1); see signal(7)"; +// ok = false; +// return QByteArray(); +// break; +// case EINVAL: +// qDebug() << "Unlock failed: Invalid argument (POSIX.1)"; +// ok = false; +// return QByteArray(); +// break; +// case EAGAIN: +// qDebug() << "Unlock failed: Resource temporarily unavailable (may be the same value as EWOULDBLOCK) (POSIX.1)"; +// ok = false; +// return QByteArray(); +// break; +// case ETIMEDOUT: +// qDebug() << "Unlock failed: Connection timed out (POSIX.1)"; +// ok = false; +// return QByteArray(); +// break; +// } + if (err < 0) { + ok = false; + return QByteArray(); + } + + if (!shmLock()) { + ok = false; + return QByteArray(); + } + } + + if (!resizeShm()) { + qDebug() << "Could not resize shared memory"; + ok = false; + return QByteArray(); + } + + if (data.size() != m_pShmArea->m_BufferSize) + data.resize(m_pShmArea->m_BufferSize); + memcpy(data.data(),m_pShmArea->m_Data,m_pShmArea->m_BufferSize); + m_BufferGen = m_pShmArea->m_BufferGen; + shmUnlock(); + return data; +} + +///Connect to the shared memory +bool VideoRenderer::startShm() +{ + if (fd != -1) { + qDebug() << "fd must be -1"; + return false; + } + + fd = shm_open(m_ShmPath.toAscii(), O_RDWR, 0); + if (fd < 0) { + qDebug() << "could not open shm area \"%s\", shm_open failed:%s" << m_ShmPath << strerror(errno); + return false; + } + m_ShmAreaLen = sizeof(SHMHeader); + m_pShmArea = (SHMHeader*) mmap(NULL, m_ShmAreaLen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (m_pShmArea == MAP_FAILED) { + qDebug() << "Could not map shm area, mmap failed"; + return false; + } + return true; +} + +///Disconnect from the shared memory +void VideoRenderer::stopShm() +{ + if (fd >= 0) + close(fd); + fd = -1; + + if (m_pShmArea != MAP_FAILED) + munmap(m_pShmArea, m_ShmAreaLen); + m_ShmAreaLen = 0; + m_pShmArea = (SHMHeader*) MAP_FAILED; +} + +///Resize the shared memory +bool VideoRenderer::resizeShm() +{ + while ((sizeof(SHMHeader) + m_pShmArea->m_BufferSize) > m_ShmAreaLen) { + const size_t new_size = sizeof(SHMHeader) + m_pShmArea->m_BufferSize; + + shmUnlock(); + if (munmap(m_pShmArea, m_ShmAreaLen)) { + qDebug() << "Could not unmap shared area:%s" << strerror(errno); + return false; + } + + m_pShmArea = (SHMHeader*) mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + m_ShmAreaLen = new_size; + + if (!m_pShmArea) { + m_pShmArea = 0; + qDebug() << "Could not remap shared area"; + return false; + } + + m_ShmAreaLen = new_size; + if (!shmLock()) + return false; + } + return true; +} + +///Lock the memory while the copy is being made +bool VideoRenderer::shmLock() +{ + const timespec timeout = createTimeout(); + /* We need an upper limit on how long we'll wait to avoid locking the whole GUI */ + if (sem_timedwait(&m_pShmArea->mutex, &timeout) == ETIMEDOUT) { + qDebug() << "Timed out before shm lock was acquired"; + return false; + } + return true; +} + +///Remove the lock, allow a new frame to be drawn +void VideoRenderer::shmUnlock() +{ + sem_post(&m_pShmArea->mutex); +} + +///Create a SHM timeout +timespec VideoRenderer::createTimeout() +{ + timespec timeout = {0, 0}; + if (clock_gettime(CLOCK_REALTIME, &timeout) == -1) + qDebug() << "clock_gettime"; + timeout.tv_sec += TIMEOUT_SEC; + return timeout; +} + + +/***************************************************************************** + * * + * Slots * + * * + ****************************************************************************/ + +///Update the buffer +void VideoRenderer::timedEvents() +{ + bool ok = true; + QByteArray ba; + renderToBitmap(m_Frame,ok); + if (ok == true) { + qDebug() << "Emit"; + emit frameUpdated(); + } + else { + qDebug() << "Frame dropped"; + usleep(rand()%100000); //Be sure it can come back in sync + } +} + +///Start the rendering loop +void VideoRenderer::startRendering() +{ + startShm(); + if (!m_pTimer) { + m_pTimer = new QTimer(this); + connect(m_pTimer,SIGNAL(timeout()),this,SLOT(timedEvents())); + m_pTimer->setInterval(42); + } + m_pTimer->start(); + m_isRendering = true; +} + +///Stop the rendering loop +void VideoRenderer::stopRendering() +{ + m_isRendering = false; + stopShm(); + //qDebug() << "Video stopped for call" << id; + //emit videoStopped(); + if (m_pTimer) + m_pTimer->stop(); +} + + +/***************************************************************************** + * * + * Getters * + * * + ****************************************************************************/ + +///Get the raw bytes directly from the SHM, not recommanded, but optimal +const char* VideoRenderer::rawData() +{ + return m_pShmArea->m_Data; +} + +///Is this redenrer active +bool VideoRenderer::isRendering() +{ + return m_isRendering; +} + +///Return the current framerate +QByteArray VideoRenderer::getCurrentFrame() +{ + return m_Frame; +} + +///Return the current resolution +Resolution VideoRenderer::getActiveResolution() +{ + return m_Res; +} + +/***************************************************************************** + * * + * Setters * + * * + ****************************************************************************/ + +void VideoRenderer::setResolution(QSize size) +{ + m_Res = size; + m_Width = size.width(); + m_Height = size.height(); +} + +void VideoRenderer::setShmPath(QString path) +{ + m_ShmPath = path; +} \ No newline at end of file diff --git a/kde/src/lib/VideoRenderer.h b/kde/src/lib/VideoRenderer.h new file mode 100644 index 0000000000000000000000000000000000000000..bfbfa45ef10762d82ebe80d06645638c39fc756a --- /dev/null +++ b/kde/src/lib/VideoRenderer.h @@ -0,0 +1,93 @@ +/************************************************************************************ + * Copyright (C) 2012 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 Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***********************************************************************************/ +#ifndef VIDEO_RENDERER_H +#define VIDEO_RENDERER_H + +//Base +#include <QtCore/QObject> +#include "typedefs.h" + +//Qt +class QTimer; + +//SFLPhone +#include "VideoDevice.h" +struct SHMHeader; + +///Manage shared memory and convert it to QByteArray +class LIB_EXPORT VideoRenderer : public QObject { + Q_OBJECT + + public: + //Constructor + VideoRenderer (QString shmPath,Resolution res); + ~VideoRenderer(); + + //Mutators + bool resizeShm(); + void stopShm (); + bool startShm (); + + //Getters + QByteArray renderToBitmap(QByteArray& data, bool& ok); + const char* rawData (); + bool isRendering (); + QByteArray getCurrentFrame (); + Resolution getActiveResolution(); + + //Setters + void setResolution(QSize size); + void setShmPath (QString path); + + private: + //Attributes + uint m_Width ; + uint m_Height ; + QString m_ShmPath ; + int fd ; + SHMHeader* m_pShmArea ; + signed int m_ShmAreaLen ; + uint m_BufferGen ; + bool m_isRendering; + QTimer* m_pTimer ; + QByteArray m_Frame ; + Resolution m_Res ; + + //Constants + static const int TIMEOUT_SEC = 1; // 1 second + + //Helpers + timespec createTimeout(); + bool shmLock (); + void shmUnlock (); + + private slots: + void timedEvents(); + + public slots: + void startRendering(); + void stopRendering (); + + signals: + ///Emitted when a new frame is ready + void frameUpdated(); + +}; + +#endif \ No newline at end of file diff --git a/kde/src/lib/sflphone_const.h b/kde/src/lib/sflphone_const.h index 448a28eb304e5fea224df73027ff125acdcb4e48..06a8d7009879b0c59ac7495821d5f6ffe40b5de2 100644 --- a/kde/src/lib/sflphone_const.h +++ b/kde/src/lib/sflphone_const.h @@ -222,8 +222,6 @@ #define CALL_STATE_CHANGE_BUSY "BUSY" #define CALL_STATE_CHANGE_FAILURE "FAILURE" #define CALL_STATE_CHANGE_UNHOLD_CURRENT "UNHOLD_CURRENT" -#define CALL_STATE_CHANGE_UNHOLD_RECORD "UNHOLD_RECORD" -#define CALL_STATE_CHANGE_RECORD "RECORD" #define CALL_STATE_CHANGE_UNKNOWN "UNKNOWN" #define CONF_STATE_CHANGE_HOLD "HOLD" @@ -235,7 +233,6 @@ #define DAEMON_CALL_STATE_INIT_INCOMING "INCOMING" #define DAEMON_CALL_STATE_INIT_RINGING "RINGING" #define DAEMON_CALL_STATE_INIT_INACTIVE "INACTIVE" -#define DAEMON_CALL_STATE_INIT_RECORD "RECORD" #define DAEMON_CALL_TYPE_INCOMING "0" #define DAEMON_CALL_TYPE_OUTGOING "1" @@ -289,7 +286,6 @@ typedef enum CALL_STATE_ERROR = 10,/** This state should never be reached */ CALL_STATE_CONFERENCE = 11,/** This call is the current conference*/ CALL_STATE_CONFERENCE_HOLD = 12,/** This call is a conference on hold*/ - CALL_STATE_RECORD = 13,/** When the call start as recorging instead of current*/ } call_state; static const QString empty(""); diff --git a/kde/src/lib/video_interface_singleton.h b/kde/src/lib/video_interface_singleton.h index e594b967642a72aafff4e6548152ab74cbd1f1af..ea6192e0c15d4ea97b2ecd392be3000c971c3334 100644 --- a/kde/src/lib/video_interface_singleton.h +++ b/kde/src/lib/video_interface_singleton.h @@ -17,14 +17,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***********************************************************************************/ -#ifndef INSTANCE_INTERFACE_SINGLETON_H -#define INSTANCE_INTERFACE_SINGLETON_H +#ifndef VIDEO_INTERFACE_SINGLETON_H +#define VIDEO_INTERFACE_SINGLETON_H #include "src/lib/video_dbus_interface.h" #include "typedefs.h" /** - * @author Jérémy Quentin <jeremy.quentin@savoirfairelinux.com> + * @author Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> */ class LIB_EXPORT VideoInterfaceSingleton { diff --git a/kde/src/widgets/AcceleratedVideoWidget.cpp b/kde/src/widgets/AcceleratedVideoWidget.cpp index c27d79a8fc918b3ceae99f56a827f77e5257e609..3c3dd2dc883bbd53290d8770dba250b69fb690af 100644 --- a/kde/src/widgets/AcceleratedVideoWidget.cpp +++ b/kde/src/widgets/AcceleratedVideoWidget.cpp @@ -21,6 +21,7 @@ #include <QPixmap> #include <KDebug> #include "../lib/VideoModel.h" +#include "../lib/VideoRenderer.h" @@ -317,8 +318,8 @@ Cube *CubeBuilder::newCube(const QVector3D &loc) const void AcceleratedVideoWidget::newFrameEvent() { qDebug() << "New frame event"; - QSize size(VideoModel::getInstance()->getActiveResolution().width, VideoModel::getInstance()->getActiveResolution().height); - m_Image = QImage((uchar*)VideoModel::getInstance()->rawData() , size.width(), size.height(), QImage::Format_ARGB32 ); + QSize size(VideoModel::getInstance()->getRenderer()->getActiveResolution().width, VideoModel::getInstance()->getRenderer()->getActiveResolution().height); + m_Image = QImage((uchar*)VideoModel::getInstance()->getRenderer()->rawData() , size.width(), size.height(), QImage::Format_ARGB32 ); paintGL(); } @@ -374,7 +375,7 @@ static GLfloat colorArray[][4] = { void AcceleratedVideoWidget::paintGL() { - QSize size(VideoModel::getInstance()->getActiveResolution().width, VideoModel::getInstance()->getActiveResolution().height); + QSize size(VideoModel::getInstance()->getRenderer()->getActiveResolution().width, VideoModel::getInstance()->getRenderer()->getActiveResolution().height); if (size != minimumSize()) setMinimumSize(size); diff --git a/kde/src/widgets/ContactDock.cpp b/kde/src/widgets/ContactDock.cpp index 5f8247e1531c440d821488d63857fa6f490eddf6..a451bc37565ce46f782afecd4f88243a42ad65ae 100644 --- a/kde/src/widgets/ContactDock.cpp +++ b/kde/src/widgets/ContactDock.cpp @@ -414,7 +414,7 @@ void ContactDock::keyPressEvent(QKeyEvent* event) { QNumericTreeWidgetItem_hist* item = dynamic_cast<QNumericTreeWidgetItem_hist*>(m_pContactView->selectedItems()[0]); if (item) { Call* call = NULL; - SFLPhone::app()->view()->selectCallPhoneNumber(call,item->widget->getContact()); + SFLPhone::app()->view()->selectCallPhoneNumber(&call,item->widget->getContact()); } } } diff --git a/kde/src/widgets/VideoWidget.cpp b/kde/src/widgets/VideoWidget.cpp index 61884b1f7e6cfdc7bc23f70c17c42f107f2b931b..ba29e2b25ddb791a37ec604e3d63c0953141cb8b 100644 --- a/kde/src/widgets/VideoWidget.cpp +++ b/kde/src/widgets/VideoWidget.cpp @@ -17,6 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***********************************************************************************/ #include "VideoWidget.h" +#include "../lib/VideoRenderer.h" #include <KDebug> ///Constructor @@ -31,7 +32,7 @@ VideoWidget::VideoWidget(QWidget* parent) : QWidget(parent),m_Image(nullptr) { void VideoWidget::update() { kDebug() << "Painting" << this; QPainter painter(this); - if (m_Image && VideoModel::getInstance()->isRendering()) + if (m_Image && VideoModel::getInstance()->getRenderer()->isRendering()) painter.drawImage(QRect(0,0,width(),height()),*(m_Image)); painter.end(); } @@ -48,13 +49,13 @@ void VideoWidget::paintEvent(QPaintEvent* event) ///Called when a new frame is ready void VideoWidget::updateFrame() { - QSize size(VideoModel::getInstance()->getActiveResolution().width, VideoModel::getInstance()->getActiveResolution().height); + QSize size(VideoModel::getInstance()->getRenderer()->getActiveResolution().width, VideoModel::getInstance()->getRenderer()->getActiveResolution().height); if (size != minimumSize()) setMinimumSize(size); if (m_Image) delete m_Image; //if (!m_Image && VideoModel::getInstance()->isRendering()) - m_Image = new QImage((uchar*)VideoModel::getInstance()->rawData() , size.width(), size.height(), QImage::Format_ARGB32 ); + m_Image = new QImage((uchar*)VideoModel::getInstance()->getRenderer()->rawData() , size.width(), size.height(), QImage::Format_ARGB32 ); //This is the right way to do it, but it does not work // if (!m_Image || (m_Image && m_Image->size() != size)) // m_Image = new QImage((uchar*)VideoModel::getInstance()->rawData() , size.width(), size.height(), QImage::Format_ARGB32 );