1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-09-10 12:03:18 +02:00

video: fix rendering on linux

Change-Id: If6a2deda08663f7edf9fa527bc1c592f60e6a371
This commit is contained in:
Andreas Traczyk 2020-11-03 17:28:25 -05:00 committed by Ming Rui Zhang
parent fc3eed8a4b
commit c472fe83ae
18 changed files with 170 additions and 257 deletions

View file

@ -231,16 +231,16 @@ AccountAdapter::savePassword(const QString& accountId,
} }
void void
AccountAdapter::startPreviewing(bool force, bool async) AccountAdapter::startPreviewing(bool force)
{ {
LRCInstance::renderer()->startPreviewing(force, async); LRCInstance::renderer()->startPreviewing(force);
} }
void void
AccountAdapter::stopPreviewing(bool async) AccountAdapter::stopPreviewing()
{ {
if (!LRCInstance::hasVideoCall() && LRCInstance::renderer()->isPreviewing()) { if (!LRCInstance::hasVideoCall() && LRCInstance::renderer()->isPreviewing()) {
LRCInstance::renderer()->stopPreviewing(async); LRCInstance::renderer()->stopPreviewing();
} }
} }

View file

@ -93,8 +93,8 @@ public:
const QString& oldPassword, const QString& oldPassword,
const QString& newPassword); const QString& newPassword);
Q_INVOKABLE void startPreviewing(bool force = false, bool async = true); Q_INVOKABLE void startPreviewing(bool force = false);
Q_INVOKABLE void stopPreviewing(bool async = true); Q_INVOKABLE void stopPreviewing();
Q_INVOKABLE bool hasVideoCall(); Q_INVOKABLE bool hasVideoCall();
Q_INVOKABLE bool isPreviewing(); Q_INVOKABLE bool isPreviewing();
Q_INVOKABLE void setCurrAccDisplayName(const QString& text); Q_INVOKABLE void setCurrAccDisplayName(const QString& text);

View file

@ -1,4 +1,4 @@
/* /*
* Copyright (C) 2020 by Savoir-faire Linux * Copyright (C) 2020 by Savoir-faire Linux
* Author : Edric Ladent Milaret<edric.ladent - milaret @savoirfairelinux.com> * Author : Edric Ladent Milaret<edric.ladent - milaret @savoirfairelinux.com>
* Author : Andreas Traczyk<andreas.traczyk @savoirfairelinux.com> * Author : Andreas Traczyk<andreas.traczyk @savoirfairelinux.com>
@ -21,25 +21,25 @@
#include "avadapter.h" #include "avadapter.h"
#include "lrcinstance.h" #include "lrcinstance.h"
#include "qtutils.h"
#include <QtConcurrent/QtConcurrent>
#include <QApplication> #include <QApplication>
#include <QScreen> #include <QScreen>
AvAdapter::AvAdapter(QObject* parent) AvAdapter::AvAdapter(QObject* parent)
: QmlAdapterBase(parent) : QmlAdapterBase(parent)
{} {
auto& avModel = LRCInstance::avModel();
deviceListSize_ = avModel.getDevices().size();
connect(&avModel, &lrc::api::AVModel::deviceEvent, this, &AvAdapter::slotDeviceEvent);
}
QVariantMap QVariantMap
AvAdapter::populateVideoDeviceContextMenuItem() AvAdapter::populateVideoDeviceContextMenuItem()
{ {
auto* convModel = LRCInstance::getCurrentConversationModel(); auto activeDevice = LRCInstance::avModel().getCurrentVideoCaptureDevice();
const auto conversation = convModel->getConversationForUID(LRCInstance::getCurrentConvUid());
auto call = LRCInstance::getCallInfoForConversation(conversation);
if (!call) {
return QVariantMap();
}
auto activeDevice = LRCInstance::avModel().getCurrentRenderedDevice(call->id);
/* /*
* Create a list of video input devices. * Create a list of video input devices.
@ -49,7 +49,7 @@ AvAdapter::populateVideoDeviceContextMenuItem()
for (int i = 0; i < devices.size(); i++) { for (int i = 0; i < devices.size(); i++) {
try { try {
auto settings = LRCInstance::avModel().getDeviceSettings(devices[i]); auto settings = LRCInstance::avModel().getDeviceSettings(devices[i]);
deciveContextMenuNeededInfo[settings.name] = QVariant(devices[i] == activeDevice.name); deciveContextMenuNeededInfo[settings.name] = QVariant(settings.id == activeDevice);
} catch (...) { } catch (...) {
qDebug().noquote() << "Error in getting device settings"; qDebug().noquote() << "Error in getting device settings";
} }
@ -138,3 +138,66 @@ AvAdapter::stopAudioMeter(bool async)
{ {
LRCInstance::stopAudioMeter(async); LRCInstance::stopAudioMeter(async);
} }
void
AvAdapter::slotDeviceEvent()
{
auto& avModel = LRCInstance::avModel();
auto defaultDevice = avModel.getDefaultDevice();
auto currentCaptureDevice = avModel.getCurrentVideoCaptureDevice();
QString callId {};
auto* convModel = LRCInstance::getCurrentConversationModel();
const auto conversation = convModel->getConversationForUID(LRCInstance::getCurrentConvUid());
auto call = LRCInstance::getCallInfoForConversation(conversation);
if (call)
callId = call->id;
/*
* Decide whether a device has plugged, unplugged, or nothing has changed.
*/
auto deviceList = avModel.getDevices();
auto currentDeviceListSize = deviceList.size();
DeviceEvent deviceEvent {DeviceEvent::None};
if (currentDeviceListSize > deviceListSize_) {
deviceEvent = DeviceEvent::Added;
} else if (currentDeviceListSize < deviceListSize_) {
/*
* Check if the currentCaptureDevice is still in the device list.
*/
if (std::find(std::begin(deviceList), std::end(deviceList), currentCaptureDevice)
== std::end(deviceList)) {
deviceEvent = DeviceEvent::RemovedCurrent;
}
}
auto cb = [this, currentDeviceListSize, deviceEvent, defaultDevice, callId] {
auto& avModel = LRCInstance::avModel();
if (currentDeviceListSize == 0) {
avModel.clearCurrentVideoCaptureDevice();
avModel.switchInputTo({}, callId);
avModel.stopPreview();
} else if (deviceEvent == DeviceEvent::RemovedCurrent && currentDeviceListSize > 0) {
avModel.switchInputTo(defaultDevice, callId);
avModel.setCurrentVideoCaptureDevice(defaultDevice);
}
};
if (LRCInstance::renderer()->isPreviewing()) {
Utils::oneShotConnect(LRCInstance::renderer(),
&RenderManager::previewRenderingStopped,
[cb] { QtConcurrent::run([cb]() { cb(); }); });
} else {
if (deviceEvent == DeviceEvent::Added && currentDeviceListSize == 1) {
avModel.switchInputTo(defaultDevice, callId);
avModel.setCurrentVideoCaptureDevice(defaultDevice);
} else {
cb();
}
}
emit videoDeviceListChanged();
deviceListSize_ = currentDeviceListSize;
}

View file

@ -32,6 +32,13 @@ public:
explicit AvAdapter(QObject* parent = nullptr); explicit AvAdapter(QObject* parent = nullptr);
~AvAdapter() = default; ~AvAdapter() = default;
signals:
/*
* Emitted when the size of the video capture device list changes.
*/
void videoDeviceListChanged();
protected: protected:
void safeInit() override {}; void safeInit() override {};
@ -67,4 +74,20 @@ protected:
Q_INVOKABLE void startAudioMeter(bool async); Q_INVOKABLE void startAudioMeter(bool async);
Q_INVOKABLE void stopAudioMeter(bool async); Q_INVOKABLE void stopAudioMeter(bool async);
private:
/*
* Used to classify capture device events.
*/
enum class DeviceEvent { Added, RemovedCurrent, None };
/*
* Used to track the capture device count.
*/
int deviceListSize_;
/*
* Device changed slot.
*/
void slotDeviceEvent();
}; };

View file

@ -34,8 +34,8 @@ ColumnLayout {
setAvatarImage(AvatarImage.Mode.Default, "") setAvatarImage(AvatarImage.Mode.Default, "")
} }
function startBooth(force = false) { function startBooth() {
AccountAdapter.startPreviewing(force) AccountAdapter.startPreviewing(false)
photoState = PhotoboothView.PhotoState.CameraRendering photoState = PhotoboothView.PhotoState.CameraRendering
} }

View file

@ -33,13 +33,6 @@ DistantRenderer::DistantRenderer(QQuickItem* parent)
if (distantRenderId_ == id) if (distantRenderId_ == id)
update(QRect(0, 0, width(), height())); update(QRect(0, 0, width(), height()));
}); });
connect(LRCInstance::renderer(),
&RenderManager::distantRenderingStopped,
[this](const QString& id) {
if (distantRenderId_ == id)
update(QRect(0, 0, width(), height()));
});
} }
DistantRenderer::~DistantRenderer() {} DistantRenderer::~DistantRenderer() {}
@ -48,7 +41,6 @@ void
DistantRenderer::setRendererId(const QString& id) DistantRenderer::setRendererId(const QString& id)
{ {
distantRenderId_ = id; distantRenderId_ = id;
update(QRect(0, 0, width(), height()));
} }
int int
@ -99,4 +91,4 @@ DistantRenderer::paint(QPainter* painter)
painter->drawImage(QRect(xOffset_, yOffset_, scaledDistant.width(), scaledDistant.height()), painter->drawImage(QRect(xOffset_, yOffset_, scaledDistant.width(), scaledDistant.height()),
scaledDistant); scaledDistant);
} }
} }

View file

@ -235,12 +235,6 @@ Rectangle {
VideoCallPreviewRenderer { VideoCallPreviewRenderer {
id: previewRenderer id: previewRenderer
// Property is used in the {} expression for height (extra dependency),
// it will not affect the true height expression, since expression
// at last will be taken only, but it will force the height to update
// and reevaluate getPreviewImageScalingFactor().
property int previewImageScalingFactorUpdated: 0
Connections { Connections {
target: CallAdapter target: CallAdapter
@ -250,10 +244,6 @@ Rectangle {
} }
width: Math.max(videoCallPageMainRect.width / 5, JamiTheme.minimumPreviewWidth) width: Math.max(videoCallPageMainRect.width / 5, JamiTheme.minimumPreviewWidth)
height: {
previewImageScalingFactorUpdated
return previewRenderer.width * previewRenderer.getPreviewImageScalingFactor()
}
x: videoCallPageMainRect.width - previewRenderer.width - previewMargin x: videoCallPageMainRect.width - previewRenderer.width - previewMargin
y: videoCallPageMainRect.height - previewRenderer.height - previewMargin - 56 // Avoid overlay y: videoCallPageMainRect.height - previewRenderer.height - previewMargin - 56 // Avoid overlay
z: -1 z: -1
@ -313,9 +303,11 @@ Rectangle {
} }
} }
onPreviewImageAvailable: { onWidthChanged: {
previewImageScalingFactorUpdated++ previewRenderer.height = previewRenderer.width * previewImageScalingFactor
previewImageScalingFactorUpdated-- }
onPreviewImageScalingFactorChanged: {
previewRenderer.height = previewRenderer.width * previewImageScalingFactor
} }
} }
} }

View file

@ -32,15 +32,11 @@ PreviewRenderer::PreviewRenderer(QQuickItem* parent)
previewFrameUpdatedConnection_ = connect(LRCInstance::renderer(), previewFrameUpdatedConnection_ = connect(LRCInstance::renderer(),
&RenderManager::previewFrameUpdated, &RenderManager::previewFrameUpdated,
[this]() { update(QRect(0, 0, width(), height())); }); [this]() { update(QRect(0, 0, width(), height())); });
previewRenderingStopped_ = connect(LRCInstance::renderer(),
&RenderManager::previewRenderingStopped,
[this]() { update(QRect(0, 0, width(), height())); });
} }
PreviewRenderer::~PreviewRenderer() PreviewRenderer::~PreviewRenderer()
{ {
disconnect(previewFrameUpdatedConnection_); disconnect(previewFrameUpdatedConnection_);
disconnect(previewRenderingStopped_);
} }
void void
@ -71,30 +67,20 @@ PreviewRenderer::paint(QPainter* painter)
} }
VideoCallPreviewRenderer::VideoCallPreviewRenderer(QQuickItem* parent) VideoCallPreviewRenderer::VideoCallPreviewRenderer(QQuickItem* parent)
: PreviewRenderer(parent) : PreviewRenderer(parent) {
{} setProperty("previewImageScalingFactor", 1.0);
}
VideoCallPreviewRenderer::~VideoCallPreviewRenderer() {} VideoCallPreviewRenderer::~VideoCallPreviewRenderer() {}
qreal
VideoCallPreviewRenderer::getPreviewImageScalingFactor()
{
auto previewImage = LRCInstance::renderer()->getPreviewFrame();
if (previewImage) {
return static_cast<qreal>(previewImage->height())
/ static_cast<qreal>(previewImage->width());
}
return 1.0;
}
void void
VideoCallPreviewRenderer::paint(QPainter* painter) VideoCallPreviewRenderer::paint(QPainter* painter)
{ {
auto previewImage = LRCInstance::renderer()->getPreviewFrame(); auto previewImage = LRCInstance::renderer()->getPreviewFrame();
if (previewImage) { if (previewImage) {
emit previewImageAvailable(); auto scalingFactor = static_cast<qreal>(previewImage->height())
/ static_cast<qreal>(previewImage->width());
setProperty("previewImageScalingFactor", scalingFactor);
QImage scaledPreview; QImage scaledPreview;
scaledPreview = previewImage->scaled(size().toSize(), Qt::KeepAspectRatio); scaledPreview = previewImage->scaled(size().toSize(), Qt::KeepAspectRatio);
painter->drawImage(QRect(0, 0, scaledPreview.width(), scaledPreview.height()), painter->drawImage(QRect(0, 0, scaledPreview.width(), scaledPreview.height()),

View file

@ -37,23 +37,23 @@ protected:
private: private:
QMetaObject::Connection previewFrameUpdatedConnection_; QMetaObject::Connection previewFrameUpdatedConnection_;
QMetaObject::Connection previewRenderingStopped_;
}; };
class VideoCallPreviewRenderer : public PreviewRenderer class VideoCallPreviewRenderer : public PreviewRenderer
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(qreal previewImageScalingFactor MEMBER previewImageScalingFactor_
NOTIFY previewImageScalingFactorChanged)
public: public:
explicit VideoCallPreviewRenderer(QQuickItem* parent = 0); explicit VideoCallPreviewRenderer(QQuickItem* parent = 0);
virtual ~VideoCallPreviewRenderer(); virtual ~VideoCallPreviewRenderer();
Q_INVOKABLE qreal getPreviewImageScalingFactor();
signals: signals:
void previewImageAvailable(); void previewImageScalingFactorChanged();
private: private:
void paint(QPainter* painter) override final; void paint(QPainter* painter) override final;
qreal previewImageScalingFactor_;
}; };
class PhotoboothPreviewRender : public PreviewRenderer class PhotoboothPreviewRender : public PreviewRenderer

View file

@ -137,7 +137,6 @@ registerTypes()
QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Models", AVModel, 1, 0, &LRCInstance::avModel()) QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Models", AVModel, 1, 0, &LRCInstance::avModel())
QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Models", PluginModel, 1, 0, &LRCInstance::pluginModel()) QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Models", PluginModel, 1, 0, &LRCInstance::pluginModel())
QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Models", RenderManager, 1, 0, LRCInstance::renderer())
QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Helpers", UpdateManager, 1, 0, LRCInstance::getUpdateManager()) QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Helpers", UpdateManager, 1, 0, LRCInstance::getUpdateManager())

View file

@ -19,8 +19,6 @@
#include "rendermanager.h" #include "rendermanager.h"
#include <QtConcurrent/QtConcurrent>
#include <stdexcept> #include <stdexcept>
using namespace lrc::api; using namespace lrc::api;
@ -51,6 +49,9 @@ FrameWrapper::connectStartRendering()
bool bool
FrameWrapper::startRendering() FrameWrapper::startRendering()
{ {
if (isRendering())
return true;
try { try {
renderer_ = const_cast<video::Renderer*>(&avModel_.getRenderer(id_)); renderer_ = const_cast<video::Renderer*>(&avModel_.getRenderer(id_));
} catch (std::out_of_range& e) { } catch (std::out_of_range& e) {
@ -69,15 +70,22 @@ FrameWrapper::startRendering()
renderConnections_.stopped = QObject::connect(&avModel_, renderConnections_.stopped = QObject::connect(&avModel_,
&AVModel::rendererStopped, &AVModel::rendererStopped,
this, this,
&FrameWrapper::slotRenderingStopped); &FrameWrapper::slotRenderingStopped,
Qt::DirectConnection);
return true; return true;
} }
void
FrameWrapper::stopRendering()
{
isRendering_ = false;
}
QImage* QImage*
FrameWrapper::getFrame() FrameWrapper::getFrame()
{ {
return image_.get(); return isRendering_ ? image_.get() : nullptr;
} }
bool bool
@ -99,8 +107,6 @@ FrameWrapper::slotRenderingStarted(const QString& id)
} }
isRendering_ = true; isRendering_ = true;
emit renderingStarted(id);
} }
void void
@ -140,7 +146,6 @@ FrameWrapper::slotFrameUpdated(const QString& id)
#endif #endif
} }
} }
emit frameUpdated(id); emit frameUpdated(id);
} }
@ -150,37 +155,22 @@ FrameWrapper::slotRenderingStopped(const QString& id)
if (id != id_) { if (id != id_) {
return; return;
} }
isRendering_ = false;
QObject::disconnect(renderConnections_.updated); QObject::disconnect(renderConnections_.updated);
QObject::disconnect(renderConnections_.stopped);
renderer_ = nullptr; renderer_ = nullptr;
/*
* The object's QImage pointer is reset before renderingStopped
* is emitted, allowing the listener to invoke specific behavior
* like clearing the widget or changing the UI entirely.
*/
image_.reset(); image_.reset();
isRendering_ = false;
emit renderingStopped(id); emit renderingStopped(id);
} }
RenderManager::RenderManager(AVModel& avModel) RenderManager::RenderManager(AVModel& avModel)
: avModel_(avModel) : avModel_(avModel)
{ {
deviceListSize_ = avModel_.getDevices().size();
connect(&avModel_, &lrc::api::AVModel::deviceEvent, this, &RenderManager::slotDeviceEvent);
previewFrameWrapper_ = std::make_unique<FrameWrapper>(avModel_); previewFrameWrapper_ = std::make_unique<FrameWrapper>(avModel_);
QObject::connect(previewFrameWrapper_.get(),
&FrameWrapper::renderingStarted,
[this](const QString& id) {
Q_UNUSED(id);
emit previewRenderingStarted();
});
QObject::connect(previewFrameWrapper_.get(), QObject::connect(previewFrameWrapper_.get(),
&FrameWrapper::frameUpdated, &FrameWrapper::frameUpdated,
[this](const QString& id) { [this](const QString& id) {
@ -219,37 +209,27 @@ RenderManager::getPreviewFrame()
} }
void void
RenderManager::stopPreviewing(bool async) RenderManager::stopPreviewing()
{ {
if (!previewFrameWrapper_->isRendering()) { if (!previewFrameWrapper_->isRendering()) {
return; return;
} }
if (async) { previewFrameWrapper_->stopRendering();
QtConcurrent::run([this] { avModel_.stopPreview(); }); avModel_.stopPreview();
} else {
avModel_.stopPreview();
}
} }
void void
RenderManager::startPreviewing(bool force, bool async) RenderManager::startPreviewing(bool force)
{ {
if (previewFrameWrapper_->isRendering() && !force) { if (previewFrameWrapper_->isRendering() && !force) {
return; return;
} }
auto restart = [this] { if (previewFrameWrapper_->isRendering()) {
if (previewFrameWrapper_->isRendering()) { avModel_.stopPreview();
avModel_.stopPreview();
}
avModel_.startPreview();
};
if (async) {
QtConcurrent::run(restart);
} else {
restart();
} }
avModel_.startPreview();
} }
QImage* QImage*
@ -279,21 +259,11 @@ RenderManager::addDistantRenderer(const QString& id)
/* /*
* Connect this to the FrameWrapper. * Connect this to the FrameWrapper.
*/ */
distantConnectionMap_[id].started = QObject::connect(dfw.get(),
&FrameWrapper::renderingStarted,
[this](const QString& id) {
emit distantRenderingStarted(id);
});
distantConnectionMap_[id].updated = QObject::connect(dfw.get(), distantConnectionMap_[id].updated = QObject::connect(dfw.get(),
&FrameWrapper::frameUpdated, &FrameWrapper::frameUpdated,
[this](const QString& id) { [this](const QString& id) {
emit distantFrameUpdated(id); emit distantFrameUpdated(id);
}); });
distantConnectionMap_[id].stopped = QObject::connect(dfw.get(),
&FrameWrapper::renderingStopped,
[this](const QString& id) {
emit distantRenderingStopped(id);
});
/* /*
* Connect FrameWrapper to avmodel. * Connect FrameWrapper to avmodel.
@ -319,7 +289,6 @@ RenderManager::removeDistantRenderer(const QString& id)
if (dcIt != distantConnectionMap_.end()) { if (dcIt != distantConnectionMap_.end()) {
QObject::disconnect(dcIt->second.started); QObject::disconnect(dcIt->second.started);
QObject::disconnect(dcIt->second.updated); QObject::disconnect(dcIt->second.updated);
QObject::disconnect(dcIt->second.stopped);
} }
/* /*
@ -327,48 +296,4 @@ RenderManager::removeDistantRenderer(const QString& id)
*/ */
distantFrameWrapperMap_.erase(dfwIt); distantFrameWrapperMap_.erase(dfwIt);
} }
} }
void
RenderManager::slotDeviceEvent()
{
auto defaultDevice = avModel_.getDefaultDevice();
auto currentCaptureDevice = avModel_.getCurrentVideoCaptureDevice();
/*
* Decide whether a device has plugged, unplugged, or nothing has changed.
*/
auto deviceList = avModel_.getDevices();
auto currentDeviceListSize = deviceList.size();
DeviceEvent deviceEvent {DeviceEvent::None};
if (currentDeviceListSize > deviceListSize_) {
deviceEvent = DeviceEvent::Added;
} else if (currentDeviceListSize < deviceListSize_) {
/*
* Check if the currentCaptureDevice is still in the device list.
*/
if (std::find(std::begin(deviceList), std::end(deviceList), currentCaptureDevice)
== std::end(deviceList)) {
deviceEvent = DeviceEvent::RemovedCurrent;
}
}
if (previewFrameWrapper_->isRendering()) {
if (currentDeviceListSize == 0) {
avModel_.clearCurrentVideoCaptureDevice();
avModel_.switchInputTo({});
stopPreviewing();
} else if (deviceEvent == DeviceEvent::RemovedCurrent && currentDeviceListSize > 0) {
avModel_.setCurrentVideoCaptureDevice(defaultDevice);
startPreviewing(true);
} else {
startPreviewing();
}
} else if (deviceEvent == DeviceEvent::Added && currentDeviceListSize == 1) {
avModel_.setCurrentVideoCaptureDevice(defaultDevice);
}
emit videoDeviceListChanged();
deviceListSize_ = currentDeviceListSize;
}

View file

@ -61,6 +61,11 @@ public:
*/ */
bool startRendering(); bool startRendering();
/*
* Locally disable frame access to this FrameWrapper
*/
void stopRendering();
/* /*
* Get the most recently rendered frame as a QImage. * Get the most recently rendered frame as a QImage.
* @return the rendered image of this object's id * @return the rendered image of this object's id
@ -73,11 +78,6 @@ public:
bool isRendering(); bool isRendering();
signals: signals:
/*
* Emitted once in slotRenderingStarted.
* @param id of the renderer
*/
void renderingStarted(const QString& id);
/* /*
* Emitted each time a frame is ready to be displayed. * Emitted each time a frame is ready to be displayed.
* @param id of the renderer * @param id of the renderer
@ -180,14 +180,12 @@ public:
/* /*
* Start capturing and rendering preview frames. * Start capturing and rendering preview frames.
* @param force if the capture device should be started * @param force if the capture device should be started
* @param async
*/ */
void startPreviewing(bool force = false, bool async = true); void startPreviewing(bool force = false);
/* /*
* Stop capturing. * Stop capturing.
* @param async
*/ */
void stopPreviewing(bool async = true); void stopPreviewing();
/* /*
* Get the most recently rendered distant frame for a given id * Get the most recently rendered distant frame for a given id
@ -209,15 +207,6 @@ public:
void removeDistantRenderer(const QString& id); void removeDistantRenderer(const QString& id);
signals: signals:
/*
* Emitted when the size of the video capture device list changes.
*/
void videoDeviceListChanged();
/*
* Emitted when the preview is started.
*/
void previewRenderingStarted();
/* /*
* Emitted when the preview has a new frame ready. * Emitted when the preview has a new frame ready.
@ -229,11 +218,6 @@ signals:
*/ */
void previewRenderingStopped(); void previewRenderingStopped();
/*
* Emitted when a distant renderer is started for a given id.
*/
void distantRenderingStarted(const QString& id);
/* /*
* Emitted when a distant renderer has a new frame ready for a given id. * Emitted when a distant renderer has a new frame ready for a given id.
*/ */
@ -244,23 +228,7 @@ signals:
*/ */
void distantRenderingStopped(const QString& id); void distantRenderingStopped(const QString& id);
private slots:
/*
* Used to listen to AVModel::deviceEvent.
*/
void slotDeviceEvent();
private: private:
/*
* Used to classify capture device events.
*/
enum class DeviceEvent { Added, RemovedCurrent, None };
/*
* Used to track the capture device count.
*/
int deviceListSize_;
/* /*
* One preview frame. * One preview frame.
*/ */
@ -277,4 +245,3 @@ private:
*/ */
AVModel& avModel_; AVModel& avModel_;
}; };
Q_DECLARE_METATYPE(RenderManager*)

View file

@ -41,6 +41,8 @@ Rectangle {
onVisibleChanged: { onVisibleChanged: {
if(visible){ if(visible){
setSelected(selectedMenu,true) setSelected(selectedMenu,true)
} else {
AccountAdapter.stopPreviewing()
} }
} }
@ -51,21 +53,20 @@ Rectangle {
switch(sel) { switch(sel) {
case SettingsView.Account: case SettingsView.Account:
pageIdCurrentAccountSettings.connectCurrentAccount() pageIdCurrentAccountSettings.connectCurrentAccount()
settingsViewRect.stopPreviewing() AccountAdapter.stopPreviewing()
selectedMenu = sel selectedMenu = sel
pageIdCurrentAccountSettings.updateAccountInfoDisplayed() pageIdCurrentAccountSettings.updateAccountInfoDisplayed()
break break
case SettingsView.General: case SettingsView.General:
settingsViewRect.stopPreviewing() AccountAdapter.stopPreviewing()
selectedMenu = sel selectedMenu = sel
break break
case SettingsView.Media: case SettingsView.Media:
selectedMenu = sel selectedMenu = sel
settingsViewRect.stopPreviewing()
avSettings.populateAVSettings() avSettings.populateAVSettings()
break break
case SettingsView.Plugin: case SettingsView.Plugin:
settingsViewRect.stopPreviewing() AccountAdapter.stopPreviewing()
selectedMenu = sel selectedMenu = sel
pluginSettings.populatePluginSettings() pluginSettings.populatePluginSettings()
break break
@ -83,7 +84,7 @@ Rectangle {
// slots // slots
function leaveSettingsSlot(showMainView) { function leaveSettingsSlot(showMainView) {
settingsViewRect.stopPreviewing() AccountAdapter.stopPreviewing()
settingsViewRect.stopBooth() settingsViewRect.stopBooth()
if (showMainView) if (showMainView)
settingsViewWindowNeedToShowMainViewWindow() settingsViewWindowNeedToShowMainViewWindow()
@ -118,7 +119,6 @@ Rectangle {
anchors.fill: root anchors.fill: root
color: JamiTheme.secondaryBackgroundColor color: JamiTheme.secondaryBackgroundColor
signal stopPreviewing
signal stopBooth signal stopBooth
property bool isSIP: { property bool isSIP: {

View file

@ -35,12 +35,6 @@ Rectangle {
property int contentWidth: avSettingsColumnLayout.width property int contentWidth: avSettingsColumnLayout.width
property int preferredHeight: avSettingsColumnLayout.implicitHeight property int preferredHeight: avSettingsColumnLayout.implicitHeight
onVisibleChanged: {
if (!visible) {
videoSettings.stopPreviewing()
}
}
function populateAVSettings() { function populateAVSettings() {
audioSettings.populateAudioSettings() audioSettings.populateAudioSettings()
videoSettings.populateVideoSettings() videoSettings.populateVideoSettings()

View file

@ -41,9 +41,11 @@ RowLayout {
signal indexChanged signal indexChanged
function setCurrentIndex(index) { function setCurrentIndex(index, emitIndexChanged = false) {
comboBoxOfLayout.currentIndex = index comboBoxOfLayout.currentIndex = index
modelIndex = index modelIndex = index
if (emitIndexChanged)
indexChanged()
} }
function setEnabled(status) { function setEnabled(status) {

View file

@ -38,7 +38,7 @@ ColumnLayout {
property int itemWidth property int itemWidth
Connections { Connections {
target: RenderManager target: AvAdapter
enabled: root.visible enabled: root.visible
function onVideoDeviceListChanged() { function onVideoDeviceListChanged() {
@ -54,13 +54,9 @@ ColumnLayout {
resolutionComboBoxSetting.setEnabled(count) resolutionComboBoxSetting.setEnabled(count)
fpsComboBoxSetting.setEnabled(count) fpsComboBoxSetting.setEnabled(count)
deviceComboBoxSetting.setCurrentIndex(deviceComboBoxSetting.comboModel.getCurrentSettingIndex()) deviceComboBoxSetting.setCurrentIndex(
slotDeviceBoxCurrentIndexChanged(deviceComboBoxSetting.modelIndex) deviceComboBoxSetting.comboModel.getCurrentSettingIndex(), true)
hardwareAccelControl.checked = AVModel.getHardwareAcceleration() hardwareAccelControl.checked = AVModel.getHardwareAcceleration()
try {
startPreviewing(false)
} catch (err2){ console.log("Start preview fail when populate video settings, exception: "+ err2.message) }
} }
function slotDeviceBoxCurrentIndexChanged(index) { function slotDeviceBoxCurrentIndexChanged(index) {
@ -78,12 +74,12 @@ ColumnLayout {
AVModel.setCurrentVideoCaptureDevice(deviceId) AVModel.setCurrentVideoCaptureDevice(deviceId)
AVModel.setDefaultDevice(deviceId) AVModel.setDefaultDevice(deviceId)
setFormatListForCurrentDevice() setFormatListForCurrentDevice()
startPreviewing(true) startPreviewing()
} catch(err){ console.warn(err.message) } } catch(err){ console.warn(err.message) }
} }
function startPreviewing(force = false, async = true) { function startPreviewing(force = false) {
AccountAdapter.startPreviewing(force, async) AccountAdapter.startPreviewing(force)
previewAvailable = true previewAvailable = true
} }
@ -94,15 +90,11 @@ ColumnLayout {
try { try {
resolutionComboBoxSetting.comboModel.reset() resolutionComboBoxSetting.comboModel.reset()
resolutionComboBoxSetting.setCurrentIndex(resolutionComboBoxSetting.comboModel.getCurrentSettingIndex()) resolutionComboBoxSetting.setCurrentIndex(
slotFormatCurrentIndexChanged(resolutionComboBoxSetting.modelIndex, true) resolutionComboBoxSetting.comboModel.getCurrentSettingIndex(), true)
} catch(err){ console.warn("Exception: " + err.message) } } catch(err){ console.warn("Exception: " + err.message) }
} }
function stopPreviewing(async = true) {
AccountAdapter.stopPreviewing(async)
}
function slotFormatCurrentIndexChanged(index, isResolutionIndex) { function slotFormatCurrentIndexChanged(index, isResolutionIndex) {
var resolution var resolution
var rate var rate
@ -111,7 +103,8 @@ ColumnLayout {
resolutionComboBoxSetting.comboModel.index(index, 0), resolutionComboBoxSetting.comboModel.index(index, 0),
VideoFormatResolutionModel.Resolution) VideoFormatResolutionModel.Resolution)
fpsComboBoxSetting.comboModel.currentResolution = resolution fpsComboBoxSetting.comboModel.currentResolution = resolution
fpsComboBoxSetting.setCurrentIndex(fpsComboBoxSetting.comboModel.getCurrentSettingIndex()) fpsComboBoxSetting.setCurrentIndex(
fpsComboBoxSetting.comboModel.getCurrentSettingIndex(), true)
rate = fpsComboBoxSetting.comboModel.data( rate = fpsComboBoxSetting.comboModel.data(
fpsComboBoxSetting.comboModel.index(0, 0), fpsComboBoxSetting.comboModel.index(0, 0),
VideoFormatFpsModel.FPS) VideoFormatFpsModel.FPS)
@ -221,7 +214,7 @@ ColumnLayout {
onSwitchToggled: { onSwitchToggled: {
AVModel.setHardwareAcceleration(checked) AVModel.setHardwareAcceleration(checked)
videoSettings.startPreviewing(true) startPreviewing(true)
} }
} }

View file

@ -201,26 +201,6 @@ UtilsAdapter::setCurrentCall(const QString& accountId, const QString& convUid)
accInfo.callModel->setCurrentCall(convInfo.callId); accInfo.callModel->setCurrentCall(convInfo.callId);
} }
void
UtilsAdapter::startPreviewing(bool force)
{
LRCInstance::renderer()->startPreviewing(force);
}
void
UtilsAdapter::stopPreviewing()
{
if (!LRCInstance::hasVideoCall()) {
LRCInstance::renderer()->stopPreviewing();
}
}
bool
UtilsAdapter::hasVideoCall()
{
return LRCInstance::hasVideoCall();
}
bool bool
UtilsAdapter::hasCall(const QString& accountId) UtilsAdapter::hasCall(const QString& accountId)
{ {

View file

@ -58,9 +58,6 @@ public:
Q_INVOKABLE const QStringList getCurrAccList(); Q_INVOKABLE const QStringList getCurrAccList();
Q_INVOKABLE int getAccountListSize(); Q_INVOKABLE int getAccountListSize();
Q_INVOKABLE void setCurrentCall(const QString& accountId, const QString& convUid); Q_INVOKABLE void setCurrentCall(const QString& accountId, const QString& convUid);
Q_INVOKABLE void startPreviewing(bool force);
Q_INVOKABLE void stopPreviewing();
Q_INVOKABLE bool hasVideoCall();
Q_INVOKABLE bool hasCall(const QString& accountId); Q_INVOKABLE bool hasCall(const QString& accountId);
Q_INVOKABLE const QString getCallConvForAccount(const QString& accountId); Q_INVOKABLE const QString getCallConvForAccount(const QString& accountId);
Q_INVOKABLE const QString getCallId(const QString& accountId, const QString& convUid); Q_INVOKABLE const QString getCallId(const QString& accountId, const QString& convUid);