1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-07-25 18:05:34 +02:00

feature: Add 'advanced information' call overlay

Change-Id: Ia54d01ec56e01d0c04e360ec06da87aa37fe74fe
GitLab: #510
This commit is contained in:
Nicolas Vengeon 2022-10-25 11:25:14 -04:00 committed by Sébastien Blin
parent 8a59035c8a
commit 7e9dce9c00
24 changed files with 432 additions and 252 deletions

View file

@ -46,6 +46,10 @@ AvAdapter::AvAdapter(LRCInstance* instance, QObject* parent)
&lrc::api::AVModel::rendererStarted,
this,
&AvAdapter::onRendererStarted);
connect(&lrcInstance_->avModel(),
&lrc::api::AVModel::onRendererInfosUpdated,
this,
&AvAdapter::setRenderersInfoList);
}
// The top left corner of primary screen is (0, 0).
@ -415,8 +419,15 @@ AvAdapter::getHardwareAcceleration()
{
return lrcInstance_->avModel().getHardwareAcceleration();
}
void
AvAdapter::setHardwareAcceleration(bool accelerate)
{
lrcInstance_->avModel().setHardwareAcceleration(accelerate);
}
void
AvAdapter::setRenderersInfoList(QVariantList renderersInfo)
{
set_renderersInfoList(renderersInfo);
}

View file

@ -36,6 +36,7 @@ class AvAdapter final : public QmlAdapterBase
QML_PROPERTY(bool, muteCamera)
QML_RO_PROPERTY(QStringList, windowsNames)
QML_RO_PROPERTY(QList<QVariant>, windowsIds)
QML_RO_PROPERTY(QVariantList, renderersInfoList)
public:
explicit AvAdapter(LRCInstance* instance, QObject* parent = nullptr);
@ -107,6 +108,7 @@ protected:
Q_INVOKABLE void setHardwareAcceleration(bool accelerate);
private Q_SLOTS:
void setRenderersInfoList(QVariantList renderersInfo);
void onAudioDeviceEvent();
void onRendererStarted(const QString& id, const QSize& size);

View file

@ -41,6 +41,9 @@ CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject*
: QmlAdapterBase(instance, parent)
, systemTray_(systemTray)
{
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &CallAdapter::updateAdvancedInformation);
participantsModel_.reset(new CallParticipantsModel(lrcInstance_, this));
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, participantsModel_.get(), "CallParticipantsModel");
@ -95,6 +98,19 @@ CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject*
&CallAdapter::saveConferenceSubcalls);
}
void
CallAdapter::startTimerInformation()
{
updateAdvancedInformation();
timer->start(1000);
}
void
CallAdapter::stopTimerInformation()
{
timer->stop();
}
void
CallAdapter::onAccountChanged()
{
@ -1147,6 +1163,18 @@ CallAdapter::getCallDurationTime(const QString& accountId, const QString& convUi
return QString();
}
void
CallAdapter::updateAdvancedInformation()
{
try {
auto& callModel = lrcInstance_->accountModel().getAccountInfo(accountId_).callModel;
if (callModel)
set_callInformation(QVariantList::fromList(callModel->getAdvancedInformation()));
} catch (const std::exception& e) {
qWarning() << e.what();
}
}
void
CallAdapter::preventScreenSaver(bool state)
{

View file

@ -37,8 +37,10 @@ class CallAdapter final : public QmlAdapterBase
{
Q_OBJECT
QML_PROPERTY(bool, hasCall)
QML_RO_PROPERTY(QVariantList, callInformation)
public:
QTimer* timer;
enum MuteStates { UNMUTED, LOCAL_MUTED, MODERATOR_MUTED, BOTH_MUTED };
Q_ENUM(MuteStates)
@ -49,6 +51,8 @@ protected:
void safeInit() override {};
public:
Q_INVOKABLE void startTimerInformation();
Q_INVOKABLE void stopTimerInformation();
Q_INVOKABLE void placeAudioOnlyCall();
Q_INVOKABLE void placeCall();
Q_INVOKABLE void hangUpACall(const QString& accountId, const QString& convUid);
@ -88,6 +92,7 @@ public:
const QString& accountId = {},
bool forceCallOnly = false);
Q_INVOKABLE QString getCallDurationTime(const QString& accountId, const QString& convUid);
Q_INVOKABLE void updateAdvancedInformation();
Q_SIGNALS:
void callStatusChanged(int index, const QString& accountId, const QString& convUid);

View file

@ -291,6 +291,7 @@ Item {
property string shareFile: qsTr("Share file")
property string selectShareMethod: qsTr("Select sharing method")
property string viewPlugin: qsTr("View plugin")
property string advancedInformation: qsTr("Advanced information")
property string noVideoDevice: qsTr("No video device")
property string notAvailable: qsTr("Unavailable")
property string lowerHand: qsTr("Lower hand")

View file

@ -344,6 +344,13 @@ Item {
property real swarmDetailsPageDocumentsPaperClipSize: 24
property real swarmDetailsPageDocumentsMediaSize: 175
//Call information
property real textFontPointSize: calcSize(10)
property real titleFontPointSize: calcSize(13)
property color callInfoColor: chatviewTextColor
property int callInformationElementsSpacing: 5
property int callInformationBlockSpacing: 25
// Jami switch
property real switchIndicatorRadius: 30
property real switchPreferredHeight: 25

View file

@ -0,0 +1,213 @@
/*
* Copyright (C) 2022 Savoir-faire Linux Inc.
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
*
* 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 3 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, see <https://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import Qt5Compat.GraphicalEffects
import "../../commoncomponents"
Window {
id: root
width: parent.width * 2 / 3
height: parent.height * 2 / 3
property var advancedList
property var fps
onClosing: {
CallAdapter.stopTimerInformation()
}
Rectangle {
id: container
anchors.fill: parent
color: JamiTheme.secondaryBackgroundColor
RowLayout {
id: windowContent
anchors.fill: parent
ColumnLayout {
spacing: JamiTheme.callInformationBlockSpacing
Text{
color: JamiTheme.callInfoColor
text: "Call information"
font.pointSize: JamiTheme.titleFontPointSize
}
Item {
id: itemCallInformation
Layout.fillHeight: true
Layout.fillWidth: true
clip: true
ListView {
model: advancedList
width: parent.width
height: root.height
spacing: JamiTheme.callInformationBlockSpacing
delegate: Column {
spacing: JamiTheme.callInformationElementsSpacing
Text {
color: JamiTheme.callInfoColor
text: "Call id: " + modelData.CALL_ID
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemCallInformation.width
}
Text {
color: JamiTheme.callInfoColor
text: "Video codec: " + modelData.VIDEO_CODEC
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemCallInformation.width
}
Text {
color: JamiTheme.callInfoColor
text: "Audio codec: " + modelData.AUDIO_CODEC
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemCallInformation.width
}
Text {
function stringWithoutRing(peerNumber){
return peerNumber.replace("@ring.dht","") ;
}
color: JamiTheme.callInfoColor
text: "PEER_NUMBER: " + stringWithoutRing(modelData.PEER_NUMBER)
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemCallInformation.width
}
Text {
color: JamiTheme.callInfoColor
text: "Hardware acceleration: " + modelData.HARDWARE_ACCELERATION
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemCallInformation.width
}
Text {
color: JamiTheme.callInfoColor
text: "Video min bitrate: " + modelData.VIDEO_MIN_BITRATE
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemCallInformation.width
}
Text {
color: JamiTheme.callInfoColor
text: "Video max bitrate: " + modelData.VIDEO_MAX_BITRATE
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemCallInformation.width
}
Text {
color: JamiTheme.callInfoColor
text: "Video bitrate: " + modelData.VIDEO_BITRATE
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemCallInformation.width
}
Text {
color: JamiTheme.callInfoColor
text: "Sockets: " + modelData.SOCKETS
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemCallInformation.width
}
}
}
}
}
ColumnLayout {
spacing: JamiTheme.callInformationBlockSpacing
Text {
color: JamiTheme.callInfoColor
text: "Renderers information"
font.pointSize: JamiTheme.titleFontPointSize
}
Item {
id: itemParticipantInformation
Layout.fillHeight: true
Layout.fillWidth: true
clip: true
ListView {
width: parent.width
height: root.height
spacing: JamiTheme.callInformationBlockSpacing
model: fps
delegate: Column {
spacing: JamiTheme.callInformationElementsSpacing
Text{
color: JamiTheme.callInfoColor
text: "Renderer id: " + modelData.ID
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemParticipantInformation.width
}
Text {
color: JamiTheme.callInfoColor
text: "Fps: " + modelData.FPS
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemParticipantInformation.width
}
Text {
color: JamiTheme.callInfoColor
text: "Resolution: " + modelData.RES
font.pointSize: JamiTheme.textFontPointSize
wrapMode: Text.WrapAnywhere
width: itemParticipantInformation.width
}
}
}
}
}
}
}
}

View file

@ -83,6 +83,7 @@ Item {
SelectScreenWindowCreation.destroySelectScreenWindow()
ScreenRubberBandCreation.destroyScreenRubberBandWindow()
PluginHandlerPickerCreation.closePluginHandlerPicker()
callInformationWindow.close()
}
// x, y position does not need to be translated
@ -123,6 +124,14 @@ Item {
y: root.height / 2 - sipInputPanel.height / 2
}
CallInformationWindow {
id: callInformationWindow
visible: false
advancedList: CallAdapter.callInformation
fps: AvAdapter.renderersInfoList
}
JamiFileDialog {
id: jamiFileDialog

View file

@ -176,6 +176,18 @@ ContextMenuAutoLoader {
onClicked: {
root.pluginItemClicked()
}
},
GeneralMenuItem {
id: advancedInformation
canTrigger: true
itemName: JamiStrings.advancedInformation
iconSource: JamiResources.settings_24dp_svg
onClicked: {
CallAdapter.startTimerInformation();
callInformationWindow.show()
}
}
]

View file

@ -151,6 +151,7 @@ Rectangle {
Rectangle {
id: callPageMainRect
SplitView.preferredHeight: mainColumnLayout.isHorizontal ? root.height : (root.height / 3) * 2
SplitView.preferredWidth: mainColumnLayout.isHorizontal ? (root.width / 3) * 2 : root.width
SplitView.minimumHeight: root.height / 2 + 20

View file

@ -212,5 +212,6 @@
<file>mainview/components/DocumentsScrollview.qml</file>
<file>mainview/components/FilePreview.qml</file>
<file>mainview/components/MediaPreview.qml</file>
<file>mainview/components/CallInformationWindow.qml</file>
</qresource>
</RCC>

View file

@ -278,7 +278,6 @@ set(LIBCLIENT_SOURCES
avmodel.cpp
pluginmodel.cpp
namedirectory.cpp
smartinfohub.cpp
renderer.cpp)
set(LIBCLIENT_HEADERS
@ -286,7 +285,6 @@ set(LIBCLIENT_HEADERS
globalinstances.h
pixmapmanipulatordefault.h
dbuserrorhandlerdefault.h
smartinfohub.h
vcard.h
namedirectory.h
messagelistmodel.h

View file

@ -276,8 +276,17 @@ public:
QSize getRendererSize(const QString& id);
video::Frame getRendererFrame(const QString& id);
bool useDirectRenderer() const;
/**
* Update renderers information list
*/
Q_SLOT void updateRenderersInfo();
Q_SIGNALS:
/**
* Emitted after an update of renderers information
* @param renderersInfoList Information on all renderers (RES, ID, FPS)
*/
void onRendererInfosUpdated(QVariantList renderersInfoList);
/**
* Emitted when a renderer is started
* @param id of the renderer

View file

@ -391,6 +391,12 @@ public:
QString getDisplay(const QString& windowId);
void emplaceConversationConference(const QString& callId);
/**
* Get advanced information from every current call
*/
QList<QVariant> getAdvancedInformation() const;
Q_SIGNALS:
/**

View file

@ -168,6 +168,23 @@ AVModel::~AVModel()
}
}
void
AVModel::updateRenderersInfo()
{
QVariantList renderersInfoList;
for (auto r = pimpl_->renderers_.begin(); r != pimpl_->renderers_.end(); r++) {
QVariantMap qmap;
auto& rend = r->second;
MapStringString mapInfo = rend->getInfos();
qmap.insert(rend->RES, mapInfo["RES"]);
qmap.insert(rend->ID, mapInfo["ID"]);
qmap.insert(rend->FPS, mapInfo["FPS"]);
renderersInfoList.append(qmap);
}
Q_EMIT onRendererInfosUpdated(renderersInfoList);
}
bool
AVModel::getDecodingAccelerated() const
{
@ -197,7 +214,7 @@ AVModel::setEncodingAccelerated(bool accelerate)
bool
AVModel::getHardwareAcceleration() const
{
bool result = getDecodingAccelerated() & getEncodingAccelerated();
bool result = getDecodingAccelerated() && getEncodingAccelerated();
return result;
}
void
@ -825,6 +842,12 @@ void
AVModelPimpl::addRenderer(const QString& id, const QSize& res, const QString& shmPath)
{
auto connectRenderer = [this](Renderer* renderer, const QString& id) {
connect(
renderer,
&Renderer::fpsChanged,
this,
[this, id](void) { Q_EMIT linked_.updateRenderersInfo(); },
Qt::DirectConnection);
connect(
renderer,
&Renderer::started,

View file

@ -55,8 +55,12 @@
using namespace libjami::Media;
constexpr static const char HARDWARE_ACCELERATION[] = "HARDWARE_ACCELERATION";
constexpr static const char CALL_ID[] = "CALL_ID";
static std::uniform_int_distribution<int> dis {0, std::numeric_limits<int>::max()};
static const std::map<short, QString>
sip_call_status_code_map {{0, QObject::tr("Null")},
{100, QObject::tr("Trying")},
{180, QObject::tr("Ringing")},
@ -128,6 +132,8 @@ public:
const BehaviorController& behaviorController);
~CallModelPimpl();
QVariantList callAdvancedInformation();
/**
* Send the profile VCard into a call
* @param callId
@ -397,6 +403,12 @@ CallModel::createCall(const QString& uri, bool isAudioOnly, VectorMapStringStrin
return callId;
}
QList<QVariant>
CallModel::getAdvancedInformation() const
{
return pimpl_->callAdvancedInformation();
}
void
CallModel::muteMedia(const QString& callId, const QString& label, bool mute)
{
@ -950,6 +962,25 @@ CallModelPimpl::CallModelPimpl(const CallModel& linked,
CallModelPimpl::~CallModelPimpl() {}
QVariantList
CallModelPimpl::callAdvancedInformation()
{
QVariantList advancedInformationList;
QStringList callList = CallManager::instance().getCallList(linked.owner.id);
for (const auto& callId : callList) {
MapStringString mapStringDetailsList = CallManager::instance()
.getCallDetails(linked.owner.id, callId);
QVariantMap detailsList = mapStringStringToQVariantMap(mapStringDetailsList);
detailsList.insert(CALL_ID, callId);
detailsList.insert(HARDWARE_ACCELERATION, lrc.getAVModel().getHardwareAcceleration());
advancedInformationList.append(detailsList);
}
return advancedInformationList;
}
void
CallModelPimpl::initCallFromDaemon()
{

View file

@ -33,10 +33,19 @@ using namespace lrc::api::video;
struct DirectRenderer::Impl : public QObject
{
Q_OBJECT
private:
int fpsC;
int fps;
public:
std::chrono::time_point<std::chrono::system_clock> lastFrameDebug;
Impl(DirectRenderer* parent)
: QObject(nullptr)
, parent_(parent)
, fpsC(0)
, fps(0)
, lastFrameDebug(std::chrono::system_clock::now())
{
configureTarget();
if (!VideoManager::instance().registerSinkTarget(parent_->id(), target))
@ -81,6 +90,16 @@ public:
QMutexLocker lk(&mutex);
frameBufferPtr = std::move(buf);
}
// compute FPS
++fpsC;
auto currentTime = std::chrono::system_clock::now();
const std::chrono::duration<double> seconds = currentTime - lastFrameDebug;
if (seconds.count() >= FPS_RATE_SEC) {
fps = static_cast<int>(fpsC / seconds.count());
fpsC = 0;
lastFrameDebug = currentTime;
parent_->setFPS(fps);
}
Q_EMIT parent_->frameUpdated();
};

View file

@ -18,7 +18,6 @@
/* widget_p.h (_p means private) */
#include <QObject>
#include "../smartinfohub.h"
#include "typedefs.h"
#pragma once

View file

@ -43,6 +43,16 @@
#define LOG_LIBJAMI_SIGNAL4(name, arg, arg2, arg3, arg4)
#endif
inline QVariantMap
mapStringStringToQVariantMap(const MapStringString& map)
{
QVariantMap convertedMap;
for (auto i = map.begin(); i != map.end(); i++) {
convertedMap.insert(i.key(), i.value());
}
return convertedMap;
}
inline MapStringString
convertMap(const std::map<std::string, std::string>& m)
{

View file

@ -34,6 +34,12 @@ Renderer::Renderer(const QString& id, const QSize& res)
Renderer::~Renderer() {}
int
Renderer::fps() const
{
return fps_;
}
QString
Renderer::id() const
{
@ -45,6 +51,22 @@ Renderer::size() const
{
return size_;
}
void
Renderer::setFPS(int fps)
{
fps_ = fps;
Q_EMIT fpsChanged();
}
MapStringString
Renderer::getInfos() const
{
MapStringString map;
map[ID] = id();
map[FPS] = QString::number(fps());
map[RES] = QString::number(size().width()) + " * " + QString::number(size().height());
return map;
}
} // namespace video
} // namespace lrc

View file

@ -36,9 +36,19 @@ class Renderer : public QObject
{
Q_OBJECT
public:
constexpr static const char ID[] = "ID";
constexpr static const char FPS[] = "FPS";
constexpr static const char RES[] = "RES";
constexpr static const int FPS_RATE_SEC = 1;
Renderer(const QString& id, const QSize& res);
virtual ~Renderer();
/**
* @return renderer's fps
*/
int fps() const;
/**
* @return renderer's id
*/
@ -54,6 +64,13 @@ public:
*/
virtual lrc::api::video::Frame currentFrame() const = 0;
/**
* set fps
*/
void setFPS(int fps);
MapStringString getInfos() const;
public Q_SLOTS:
virtual void startRendering() = 0;
virtual void stopRendering() = 0;
@ -63,10 +80,12 @@ Q_SIGNALS:
void stopped();
void started(const QSize& size);
void frameBufferRequested(AVFrame* avFrame);
void fpsChanged();
private:
QString id_;
QSize size_;
int fps_;
};
} // namespace video

View file

@ -90,10 +90,7 @@ public:
, fpsC(0)
, fps(0)
, timer(new QTimer(this))
#ifdef DEBUG_FPS
, frameCount(0)
, lastFrameDebug(std::chrono::system_clock::now())
#endif
{
timer->setInterval(33);
connect(timer, &QTimer::timeout, [this]() { Q_EMIT parent_->frameUpdated(); });
@ -110,7 +107,6 @@ public:
}
// Constants
constexpr static const int FPS_RATE_SEC = 1;
constexpr static const int FRAME_CHECK_RATE_HZ = 120;
// Lock the memory while the copy is being made
@ -172,9 +168,10 @@ public:
auto currentTime = std::chrono::system_clock::now();
const std::chrono::duration<double> seconds = currentTime - lastFrameDebug;
if (seconds.count() >= FPS_RATE_SEC) {
fps = (int) (fpsC / seconds.count());
fps = static_cast<int>(fpsC / seconds.count());
fpsC = 0;
lastFrameDebug = currentTime;
parent_->setFPS(fps);
#ifdef DEBUG_FPS
qDebug() << this << ": FPS " << fps;
#endif

View file

@ -1,178 +0,0 @@
/****************************************************************************
* Copyright (C) 2016-2022 Savoir-faire Linux Inc. *
* Author: Olivier Grégoire <olivier.gregoire@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 "smartinfohub.h"
#include "private/smartInfoHub_p.h"
#include <dbus/videomanager.h>
#include <dbus/callmanager.h>
#include <dbus/callmanager.h>
SmartInfoHub::SmartInfoHub()
{
d_ptr = new SmartInfoHubPrivate;
connect(&CallManager::instance(),
&CallManagerInterface::SmartInfo,
this,
&SmartInfoHub::slotSmartInfo,
Qt::QueuedConnection);
}
SmartInfoHub::~SmartInfoHub() {}
void
SmartInfoHub::start()
{
CallManager::instance().startSmartInfo(d_ptr->m_refreshTimeInformationMS);
}
void
SmartInfoHub::stop()
{
CallManager::instance().stopSmartInfo();
}
SmartInfoHub&
SmartInfoHub::instance()
{
// Singleton
static SmartInfoHub instance_;
return instance_;
}
void
SmartInfoHub::setRefreshTime(uint32_t timeMS)
{
d_ptr->m_refreshTimeInformationMS = timeMS;
}
// Retrieve information from the map and implement all the variables
void
SmartInfoHub::slotSmartInfo(const MapStringString& map)
{
for (int i = 0; i < map.size(); i++)
d_ptr->m_information[map.keys().at(i)] = map[map.keys().at(i)];
Q_EMIT changed();
}
// Getter
bool
SmartInfoHub::isConference() const
{
return (d_ptr->m_information["type"] == "conference");
}
float
SmartInfoHub::localFps() const
{
if (!d_ptr->m_information[LOCAL_FPS].isEmpty())
return d_ptr->m_information[LOCAL_FPS].toFloat();
return 0.0;
}
float
SmartInfoHub::remoteFps() const
{
if (!d_ptr->m_information[REMOTE_FPS].isEmpty())
return d_ptr->m_information[REMOTE_FPS].toFloat();
return 0.0;
}
int
SmartInfoHub::remoteWidth() const
{
if (!d_ptr->m_information[REMOTE_WIDTH].isEmpty())
return d_ptr->m_information[REMOTE_WIDTH].toInt();
else
return 0;
}
int
SmartInfoHub::remoteHeight() const
{
if (!d_ptr->m_information[REMOTE_HEIGHT].isEmpty())
return d_ptr->m_information[REMOTE_HEIGHT].toInt();
else
return 0;
}
int
SmartInfoHub::localWidth() const
{
if (!d_ptr->m_information[LOCAL_WIDTH].isEmpty())
return d_ptr->m_information[LOCAL_WIDTH].toInt();
else
return 0;
}
int
SmartInfoHub::localHeight() const
{
if (!d_ptr->m_information[LOCAL_HEIGHT].isEmpty())
return d_ptr->m_information[LOCAL_HEIGHT].toInt();
else
return 0;
}
QString
SmartInfoHub::callID() const
{
if (!d_ptr->m_information[CALL_ID].isEmpty())
return d_ptr->m_information[CALL_ID];
else
return SmartInfoHubPrivate::DEFAULT_RETURN_VALUE_QSTRING;
}
QString
SmartInfoHub::localVideoCodec() const
{
if (!d_ptr->m_information[LOCAL_VIDEO_CODEC].isEmpty())
return d_ptr->m_information[LOCAL_VIDEO_CODEC];
else
return SmartInfoHubPrivate::DEFAULT_RETURN_VALUE_QSTRING;
}
QString
SmartInfoHub::localAudioCodec() const
{
if (!d_ptr->m_information[LOCAL_AUDIO_CODEC].isEmpty())
return d_ptr->m_information[LOCAL_AUDIO_CODEC];
else
return SmartInfoHubPrivate::DEFAULT_RETURN_VALUE_QSTRING;
}
QString
SmartInfoHub::remoteVideoCodec() const
{
if (!d_ptr->m_information[REMOTE_VIDEO_CODEC].isEmpty())
return d_ptr->m_information[REMOTE_VIDEO_CODEC];
else
return SmartInfoHubPrivate::DEFAULT_RETURN_VALUE_QSTRING;
}
QString
SmartInfoHub::remoteAudioCodec() const
{
if (!d_ptr->m_information[REMOTE_AUDIO_CODEC].isEmpty())
return d_ptr->m_information[REMOTE_AUDIO_CODEC];
else
return SmartInfoHubPrivate::DEFAULT_RETURN_VALUE_QSTRING;
}

View file

@ -1,65 +0,0 @@
/****************************************************************************
* Copyright (C) 2016-2022 Savoir-faire Linux Inc. *
* Author: Olivier Grégoire <olivier.gregoire@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/>. *
***************************************************************************/
#pragma once
#include <QObject>
#include "typedefs.h"
class SmartInfoHubPrivate;
class SmartInfoHub final : public QObject
{
Q_OBJECT
public:
// Singleton
static SmartInfoHub& instance();
void start();
void stop();
void setRefreshTime(uint32_t timeMS);
// Getter
float localFps() const;
float remoteFps() const;
int remoteWidth() const;
int remoteHeight() const;
int localWidth() const;
int localHeight() const;
QString callID() const;
QString localVideoCodec() const;
QString localAudioCodec() const;
QString remoteVideoCodec() const;
QString remoteAudioCodec() const;
bool isConference() const;
Q_SIGNALS:
/// Emitted when informations have changed
void changed();
private Q_SLOTS:
void slotSmartInfo(const MapStringString& info);
private:
// use to initialise the connection between the Qsignal and the lambda function
SmartInfoHub();
virtual ~SmartInfoHub();
SmartInfoHubPrivate* d_ptr;
};