Commit 46fc1b5d authored by Ronan Abhamon's avatar Ronan Abhamon

feat(app): update submodules & add a `CameraPreview` class & fix call stats

parent 2657e7c0
......@@ -93,6 +93,7 @@ set(SOURCES
src/components/call/CallModel.cpp
src/components/calls/CallsListModel.cpp
src/components/camera/Camera.cpp
src/components/camera/CameraPreview.cpp
src/components/camera/MSFunctions.cpp
src/components/chat/ChatModel.cpp
src/components/chat/ChatProxyModel.cpp
......@@ -131,6 +132,7 @@ set(HEADERS
src/components/call/CallModel.hpp
src/components/calls/CallsListModel.hpp
src/components/camera/Camera.hpp
src/components/camera/CameraPreview.hpp
src/components/camera/MSFunctions.hpp
src/components/chat/ChatModel.hpp
src/components/chat/ChatProxyModel.hpp
......
......@@ -278,6 +278,7 @@ void App::registerTypes () {
qmlRegisterType<AssistantModel>("Linphone", 1, 0, "AssistantModel");
qmlRegisterType<Authentication>("Linphone", 1, 0, "Authentication");
qmlRegisterType<Camera>("Linphone", 1, 0, "Camera");
qmlRegisterType<Camera>("Linphone", 1, 0, "CameraPreview");
qmlRegisterType<ChatModel>("Linphone", 1, 0, "ChatModel");
qmlRegisterType<ChatProxyModel>("Linphone", 1, 0, "ChatProxyModel");
qmlRegisterType<ContactsListProxyModel>("Linphone", 1, 0, "ContactsListProxyModel");
......
......@@ -24,6 +24,7 @@
#include "authentication/Authentication.hpp"
#include "calls/CallsListModel.hpp"
#include "camera/Camera.hpp"
#include "camera/CameraPreview.hpp"
#include "chat/ChatProxyModel.hpp"
#include "codecs/AudioCodecsModel.hpp"
#include "codecs/VideoCodecsModel.hpp"
......
......@@ -123,8 +123,8 @@ void CallModel::setRecordFile (shared_ptr<linphone::CallParams> &callParams) {
);
}
void CallModel::updateStats (const linphone::CallStats &stats) {
switch (stats.getType()) {
void CallModel::updateStats (const shared_ptr<const linphone::CallStats> &stats) {
switch (stats->getType()) {
case linphone::StreamTypeAudio:
updateStats(stats, mAudioStats);
break;
......@@ -426,12 +426,12 @@ inline QVariantMap createStat (const QString &key, const QString &value) {
return m;
}
void CallModel::updateStats (const linphone::CallStats &callStats, QVariantList &stats) {
void CallModel::updateStats (const shared_ptr<const linphone::CallStats> &callStats, QVariantList &stats) {
QString family;
shared_ptr<const linphone::CallParams> params = mLinphoneCall->getCurrentParams();
shared_ptr<const linphone::PayloadType> payloadType;
switch (callStats.getType()) {
switch (callStats->getType()) {
case linphone::StreamTypeAudio:
payloadType = params->getUsedAudioPayloadType();
break;
......@@ -442,7 +442,7 @@ void CallModel::updateStats (const linphone::CallStats &callStats, QVariantList
return;
}
switch (callStats.getIpFamilyOfRemote()) {
switch (callStats->getIpFamilyOfRemote()) {
case linphone::AddressFamilyInet:
family = "IPv4";
break;
......@@ -459,16 +459,16 @@ void CallModel::updateStats (const linphone::CallStats &callStats, QVariantList
stats << createStat(tr("callStatsCodec"), payloadType
? QString("%1 / %2kHz").arg(Utils::linphoneStringToQString(payloadType->getMimeType())).arg(payloadType->getClockRate() / 1000)
: "");
stats << createStat(tr("callStatsUploadBandwidth"), QString("%1 kbits/s").arg(int(callStats.getUploadBandwidth())));
stats << createStat(tr("callStatsDownloadBandwidth"), QString("%1 kbits/s").arg(int(callStats.getDownloadBandwidth())));
stats << createStat(tr("callStatsIceState"), iceStateToString(callStats.getIceState()));
stats << createStat(tr("callStatsUploadBandwidth"), QString("%1 kbits/s").arg(int(callStats->getUploadBandwidth())));
stats << createStat(tr("callStatsDownloadBandwidth"), QString("%1 kbits/s").arg(int(callStats->getDownloadBandwidth())));
stats << createStat(tr("callStatsIceState"), iceStateToString(callStats->getIceState()));
stats << createStat(tr("callStatsIpFamily"), family);
stats << createStat(tr("callStatsSenderLossRate"), QString("%1 %").arg(callStats.getSenderLossRate()));
stats << createStat(tr("callStatsReceiverLossRate"), QString("%1 %").arg(callStats.getReceiverLossRate()));
stats << createStat(tr("callStatsSenderLossRate"), QString("%1 %").arg(callStats->getSenderLossRate()));
stats << createStat(tr("callStatsReceiverLossRate"), QString("%1 %").arg(callStats->getReceiverLossRate()));
switch (callStats.getType()) {
switch (callStats->getType()) {
case linphone::StreamTypeAudio:
stats << createStat(tr("callStatsJitterBuffer"), QString("%1 ms").arg(callStats.getJitterBufferSizeMs()));
stats << createStat(tr("callStatsJitterBuffer"), QString("%1 ms").arg(callStats->getJitterBufferSizeMs()));
break;
case linphone::StreamTypeVideo: {
QString sentVideoDefinitionName = Utils::linphoneStringToQString(params->getSentVideoDefinition()->getName());
......
......@@ -72,7 +72,7 @@ public:
}
static void setRecordFile (std::shared_ptr<linphone::CallParams> &callParams);
void updateStats (const linphone::CallStats &stats);
void updateStats (const std::shared_ptr<const linphone::CallStats> &stats);
Q_INVOKABLE void accept ();
Q_INVOKABLE void acceptWithVideo ();
......@@ -126,7 +126,7 @@ private:
QVariantList getAudioStats () const;
QVariantList getVideoStats () const;
void updateStats (const linphone::CallStats &callStats, QVariantList &stats);
void updateStats (const std::shared_ptr<const linphone::CallStats> &callStats, QVariantList &stats);
QString iceStateToString (linphone::IceState state) const;
......
......@@ -20,13 +20,11 @@
* Author: Ronan Abhamon
*/
#include "../../Utils.hpp"
#include "../core/CoreManager.hpp"
#include "MSFunctions.hpp"
#include "Camera.hpp"
#include <QFileInfo>
#include <QQuickWindow>
#include <QThread>
#include <QTimer>
......@@ -91,9 +89,6 @@ QOpenGLFramebufferObject *CameraRenderer::createFramebufferObject (const QSize &
}
void CameraRenderer::render () {
if (!mLinphoneCall)
return;
// Draw with ms filter.
{
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
......@@ -101,16 +96,19 @@ void CameraRenderer::render () {
f->glClearColor(0.f, 0.f, 0.f, 0.f);
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
CoreManager *core = CoreManager::getInstance();
CoreManager *coreManager = CoreManager::getInstance();
coreManager->lockVideoRender();
MSFunctions *msFunctions = MSFunctions::getInstance();
msFunctions->bind(f);
core->lockVideoRender();
if (mIsPreview)
coreManager->getCore()->previewOglRender();
else if (mLinphoneCall)
mLinphoneCall->oglRender();
msFunctions->bind(f);
mLinphoneCall->oglRender(mIsPreview);
msFunctions->bind(nullptr);
core->unlockVideoRender();
coreManager->unlockVideoRender();
}
// Synchronize opengl calls with QML.
......
/*
* CameraPreview.cpp
* Copyright (C) 2017 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Created on: April 19, 2017
* Author: Ronan Abhamon
*/
#include "../core/CoreManager.hpp"
#include "MSFunctions.hpp"
#include "CameraPreview.hpp"
#include <QQuickWindow>
#include <QThread>
#include <QTimer>
#define MAX_FPS 30
using namespace std;
// =============================================================================
struct ContextInfo {
GLuint width;
GLuint height;
OpenGlFunctions *functions;
};
// -----------------------------------------------------------------------------
CameraPreviewRenderer::CameraPreviewRenderer () {
mContextInfo = new ContextInfo();
}
CameraPreviewRenderer::~CameraPreviewRenderer () {
qInfo() << QStringLiteral("Delete context info:") << mContextInfo;
CoreManager *core = CoreManager::getInstance();
core->lockVideoRender();
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(nullptr);
core->unlockVideoRender();
delete mContextInfo;
}
QOpenGLFramebufferObject *CameraPreviewRenderer::createFramebufferObject (const QSize &size) {
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setInternalTextureFormat(GL_RGBA8);
format.setSamples(4);
CoreManager *core = CoreManager::getInstance();
// It's not the same thread as render.
core->lockVideoRender();
mContextInfo->width = size.width();
mContextInfo->height = size.height();
mContextInfo->functions = MSFunctions::getInstance()->getFunctions();
mUpdateContextInfo = true;
updateWindowId();
core->unlockVideoRender();
return new QOpenGLFramebufferObject(size, format);
}
void CameraPreviewRenderer::render () {
// Draw with ms filter.
{
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glClearColor(0.f, 0.f, 0.f, 0.f);
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
CoreManager *coreManager = CoreManager::getInstance();
coreManager->lockVideoRender();
MSFunctions *msFunctions = MSFunctions::getInstance();
msFunctions->bind(f);
coreManager->getCore()->previewOglRender();
msFunctions->bind(nullptr);
coreManager->unlockVideoRender();
}
// Synchronize opengl calls with QML.
if (mWindow)
mWindow->resetOpenGLState();
}
void CameraPreviewRenderer::synchronize (QQuickFramebufferObject *item) {
mWindow = item->window();
}
void CameraPreviewRenderer::updateWindowId () {
if (!mUpdateContextInfo)
return;
mUpdateContextInfo = false;
qInfo() << "Thread" << QThread::currentThread() << QStringLiteral("Set context info (width: %1, height: %2):")
.arg(mContextInfo->width).arg(mContextInfo->height) << mContextInfo;
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(mContextInfo);
}
// -----------------------------------------------------------------------------
CameraPreview::CameraPreview (QQuickItem *parent) : QQuickFramebufferObject(parent) {
// The fbo content must be y-mirrored because the ms rendering is y-inverted.
setMirrorVertically(true);
mRefreshTimer = new QTimer(this);
mRefreshTimer->setInterval(1 / MAX_FPS * 1000);
QObject::connect(
mRefreshTimer, &QTimer::timeout,
this, &QQuickFramebufferObject::update,
Qt::DirectConnection
);
mRefreshTimer->start();
}
QQuickFramebufferObject::Renderer *CameraPreview::createRenderer () const {
return new CameraPreviewRenderer();
}
/*
* CameraPreview.hpp
* Copyright (C) 2017 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Created on: April 19, 2017
* Author: Ronan Abhamon
*/
#ifndef CAMERA_PREVIEW_H_
#define CAMERA_PREVIEW_H_
#include <QOpenGLFramebufferObject>
#include <QQuickFramebufferObject>
// =============================================================================
class CameraPreview;
struct ContextInfo;
class CameraPreviewRenderer : public QQuickFramebufferObject::Renderer {
friend class CameraPreview;
public:
CameraPreviewRenderer ();
~CameraPreviewRenderer ();
protected:
QOpenGLFramebufferObject *createFramebufferObject (const QSize &size) override;
void render () override;
void synchronize (QQuickFramebufferObject *item) override;
private:
void updateWindowId ();
ContextInfo *mContextInfo;
bool mUpdateContextInfo = false;
QQuickWindow *mWindow;
};
// -----------------------------------------------------------------------------
class CameraPreview : public QQuickFramebufferObject {
friend class CameraPreviewRenderer;
Q_OBJECT;
public:
CameraPreview (QQuickItem *parent = Q_NULLPTR);
~CameraPreview () = default;
QQuickFramebufferObject::Renderer *createRenderer () const override;
private:
QTimer *mRefreshTimer;
};
#endif // CAMERA_PREVIEW_H_
......@@ -55,7 +55,7 @@ void CoreHandlers::onCallStateChanged (
void CoreHandlers::onCallStatsUpdated (
const shared_ptr<linphone::Core> &,
const shared_ptr<linphone::Call> &call,
const linphone::CallStats &stats
const shared_ptr<const linphone::CallStats> &stats
) {
call->getData<CallModel>("call-model").updateStats(stats);
}
......
......@@ -57,7 +57,7 @@ private:
void onCallStatsUpdated (
const std::shared_ptr<linphone::Core> &core,
const std::shared_ptr<linphone::Call> &call,
const linphone::CallStats &stats
const std::shared_ptr<const linphone::CallStats> &stats
) override;
void onMessageReceived (
......
linphone @ 101adaea
Subproject commit 1dcd17198ee56ef54a5bb03b477575e83c29892d
Subproject commit 101adaeab8d0f39b5523a68d5d67ae594274ca89
mediastreamer2 @ dc46e818
Subproject commit 36186e9ec9ee478eacaa53b8d9e1e154d31aad89
Subproject commit dc46e818fe9b621eca3c132dfebbed39f2f232e3
ortp @ 9759554c
Subproject commit 100146d7c09aea0bddcc6a10926f1ee528d42738
Subproject commit 9759554cd788dc8254086b6a63b4cc74609b8535
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment