mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-09-10 03:53:23 +02:00
video: fix rendering on linux
Change-Id: If6a2deda08663f7edf9fa527bc1c592f60e6a371
This commit is contained in:
parent
fc3eed8a4b
commit
c472fe83ae
18 changed files with 170 additions and 257 deletions
|
@ -231,16 +231,16 @@ AccountAdapter::savePassword(const QString& accountId,
|
|||
}
|
||||
|
||||
void
|
||||
AccountAdapter::startPreviewing(bool force, bool async)
|
||||
AccountAdapter::startPreviewing(bool force)
|
||||
{
|
||||
LRCInstance::renderer()->startPreviewing(force, async);
|
||||
LRCInstance::renderer()->startPreviewing(force);
|
||||
}
|
||||
|
||||
void
|
||||
AccountAdapter::stopPreviewing(bool async)
|
||||
AccountAdapter::stopPreviewing()
|
||||
{
|
||||
if (!LRCInstance::hasVideoCall() && LRCInstance::renderer()->isPreviewing()) {
|
||||
LRCInstance::renderer()->stopPreviewing(async);
|
||||
LRCInstance::renderer()->stopPreviewing();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,8 +93,8 @@ public:
|
|||
const QString& oldPassword,
|
||||
const QString& newPassword);
|
||||
|
||||
Q_INVOKABLE void startPreviewing(bool force = false, bool async = true);
|
||||
Q_INVOKABLE void stopPreviewing(bool async = true);
|
||||
Q_INVOKABLE void startPreviewing(bool force = false);
|
||||
Q_INVOKABLE void stopPreviewing();
|
||||
Q_INVOKABLE bool hasVideoCall();
|
||||
Q_INVOKABLE bool isPreviewing();
|
||||
Q_INVOKABLE void setCurrAccDisplayName(const QString& text);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author : Edric Ladent Milaret<edric.ladent - milaret @savoirfairelinux.com>
|
||||
* Author : Andreas Traczyk<andreas.traczyk @savoirfairelinux.com>
|
||||
|
@ -21,25 +21,25 @@
|
|||
#include "avadapter.h"
|
||||
|
||||
#include "lrcinstance.h"
|
||||
#include "qtutils.h"
|
||||
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QApplication>
|
||||
#include <QScreen>
|
||||
|
||||
AvAdapter::AvAdapter(QObject* parent)
|
||||
: QmlAdapterBase(parent)
|
||||
{}
|
||||
{
|
||||
auto& avModel = LRCInstance::avModel();
|
||||
|
||||
deviceListSize_ = avModel.getDevices().size();
|
||||
connect(&avModel, &lrc::api::AVModel::deviceEvent, this, &AvAdapter::slotDeviceEvent);
|
||||
}
|
||||
|
||||
QVariantMap
|
||||
AvAdapter::populateVideoDeviceContextMenuItem()
|
||||
{
|
||||
auto* convModel = LRCInstance::getCurrentConversationModel();
|
||||
const auto conversation = convModel->getConversationForUID(LRCInstance::getCurrentConvUid());
|
||||
auto call = LRCInstance::getCallInfoForConversation(conversation);
|
||||
if (!call) {
|
||||
return QVariantMap();
|
||||
}
|
||||
|
||||
auto activeDevice = LRCInstance::avModel().getCurrentRenderedDevice(call->id);
|
||||
auto activeDevice = LRCInstance::avModel().getCurrentVideoCaptureDevice();
|
||||
|
||||
/*
|
||||
* Create a list of video input devices.
|
||||
|
@ -49,7 +49,7 @@ AvAdapter::populateVideoDeviceContextMenuItem()
|
|||
for (int i = 0; i < devices.size(); i++) {
|
||||
try {
|
||||
auto settings = LRCInstance::avModel().getDeviceSettings(devices[i]);
|
||||
deciveContextMenuNeededInfo[settings.name] = QVariant(devices[i] == activeDevice.name);
|
||||
deciveContextMenuNeededInfo[settings.name] = QVariant(settings.id == activeDevice);
|
||||
} catch (...) {
|
||||
qDebug().noquote() << "Error in getting device settings";
|
||||
}
|
||||
|
@ -138,3 +138,66 @@ AvAdapter::stopAudioMeter(bool 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;
|
||||
}
|
|
@ -32,6 +32,13 @@ public:
|
|||
explicit AvAdapter(QObject* parent = nullptr);
|
||||
~AvAdapter() = default;
|
||||
|
||||
signals:
|
||||
|
||||
/*
|
||||
* Emitted when the size of the video capture device list changes.
|
||||
*/
|
||||
void videoDeviceListChanged();
|
||||
|
||||
protected:
|
||||
void safeInit() override {};
|
||||
|
||||
|
@ -67,4 +74,20 @@ protected:
|
|||
|
||||
Q_INVOKABLE void startAudioMeter(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();
|
||||
};
|
||||
|
|
|
@ -34,8 +34,8 @@ ColumnLayout {
|
|||
setAvatarImage(AvatarImage.Mode.Default, "")
|
||||
}
|
||||
|
||||
function startBooth(force = false) {
|
||||
AccountAdapter.startPreviewing(force)
|
||||
function startBooth() {
|
||||
AccountAdapter.startPreviewing(false)
|
||||
photoState = PhotoboothView.PhotoState.CameraRendering
|
||||
}
|
||||
|
||||
|
|
|
@ -33,13 +33,6 @@ DistantRenderer::DistantRenderer(QQuickItem* parent)
|
|||
if (distantRenderId_ == id)
|
||||
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() {}
|
||||
|
@ -48,7 +41,6 @@ void
|
|||
DistantRenderer::setRendererId(const QString& id)
|
||||
{
|
||||
distantRenderId_ = id;
|
||||
update(QRect(0, 0, width(), height()));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -99,4 +91,4 @@ DistantRenderer::paint(QPainter* painter)
|
|||
painter->drawImage(QRect(xOffset_, yOffset_, scaledDistant.width(), scaledDistant.height()),
|
||||
scaledDistant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -235,12 +235,6 @@ Rectangle {
|
|||
VideoCallPreviewRenderer {
|
||||
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 {
|
||||
target: CallAdapter
|
||||
|
||||
|
@ -250,10 +244,6 @@ Rectangle {
|
|||
}
|
||||
|
||||
width: Math.max(videoCallPageMainRect.width / 5, JamiTheme.minimumPreviewWidth)
|
||||
height: {
|
||||
previewImageScalingFactorUpdated
|
||||
return previewRenderer.width * previewRenderer.getPreviewImageScalingFactor()
|
||||
}
|
||||
x: videoCallPageMainRect.width - previewRenderer.width - previewMargin
|
||||
y: videoCallPageMainRect.height - previewRenderer.height - previewMargin - 56 // Avoid overlay
|
||||
z: -1
|
||||
|
@ -313,9 +303,11 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onPreviewImageAvailable: {
|
||||
previewImageScalingFactorUpdated++
|
||||
previewImageScalingFactorUpdated--
|
||||
onWidthChanged: {
|
||||
previewRenderer.height = previewRenderer.width * previewImageScalingFactor
|
||||
}
|
||||
onPreviewImageScalingFactorChanged: {
|
||||
previewRenderer.height = previewRenderer.width * previewImageScalingFactor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,15 +32,11 @@ PreviewRenderer::PreviewRenderer(QQuickItem* parent)
|
|||
previewFrameUpdatedConnection_ = connect(LRCInstance::renderer(),
|
||||
&RenderManager::previewFrameUpdated,
|
||||
[this]() { update(QRect(0, 0, width(), height())); });
|
||||
previewRenderingStopped_ = connect(LRCInstance::renderer(),
|
||||
&RenderManager::previewRenderingStopped,
|
||||
[this]() { update(QRect(0, 0, width(), height())); });
|
||||
}
|
||||
|
||||
PreviewRenderer::~PreviewRenderer()
|
||||
{
|
||||
disconnect(previewFrameUpdatedConnection_);
|
||||
disconnect(previewRenderingStopped_);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -71,30 +67,20 @@ PreviewRenderer::paint(QPainter* painter)
|
|||
}
|
||||
|
||||
VideoCallPreviewRenderer::VideoCallPreviewRenderer(QQuickItem* parent)
|
||||
: PreviewRenderer(parent)
|
||||
{}
|
||||
: PreviewRenderer(parent) {
|
||||
setProperty("previewImageScalingFactor", 1.0);
|
||||
}
|
||||
|
||||
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
|
||||
VideoCallPreviewRenderer::paint(QPainter* painter)
|
||||
{
|
||||
auto previewImage = LRCInstance::renderer()->getPreviewFrame();
|
||||
|
||||
if (previewImage) {
|
||||
emit previewImageAvailable();
|
||||
|
||||
auto scalingFactor = static_cast<qreal>(previewImage->height())
|
||||
/ static_cast<qreal>(previewImage->width());
|
||||
setProperty("previewImageScalingFactor", scalingFactor);
|
||||
QImage scaledPreview;
|
||||
scaledPreview = previewImage->scaled(size().toSize(), Qt::KeepAspectRatio);
|
||||
painter->drawImage(QRect(0, 0, scaledPreview.width(), scaledPreview.height()),
|
||||
|
|
|
@ -37,23 +37,23 @@ protected:
|
|||
|
||||
private:
|
||||
QMetaObject::Connection previewFrameUpdatedConnection_;
|
||||
QMetaObject::Connection previewRenderingStopped_;
|
||||
};
|
||||
|
||||
class VideoCallPreviewRenderer : public PreviewRenderer
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qreal previewImageScalingFactor MEMBER previewImageScalingFactor_
|
||||
NOTIFY previewImageScalingFactorChanged)
|
||||
public:
|
||||
explicit VideoCallPreviewRenderer(QQuickItem* parent = 0);
|
||||
virtual ~VideoCallPreviewRenderer();
|
||||
|
||||
Q_INVOKABLE qreal getPreviewImageScalingFactor();
|
||||
|
||||
signals:
|
||||
void previewImageAvailable();
|
||||
void previewImageScalingFactorChanged();
|
||||
|
||||
private:
|
||||
void paint(QPainter* painter) override final;
|
||||
qreal previewImageScalingFactor_;
|
||||
};
|
||||
|
||||
class PhotoboothPreviewRender : public PreviewRenderer
|
||||
|
|
|
@ -137,7 +137,6 @@ registerTypes()
|
|||
|
||||
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", RenderManager, 1, 0, LRCInstance::renderer())
|
||||
|
||||
QML_REGISTERSINGLETONTYPE_CUSTOM("net.jami.Helpers", UpdateManager, 1, 0, LRCInstance::getUpdateManager())
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
#include "rendermanager.h"
|
||||
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace lrc::api;
|
||||
|
@ -51,6 +49,9 @@ FrameWrapper::connectStartRendering()
|
|||
bool
|
||||
FrameWrapper::startRendering()
|
||||
{
|
||||
if (isRendering())
|
||||
return true;
|
||||
|
||||
try {
|
||||
renderer_ = const_cast<video::Renderer*>(&avModel_.getRenderer(id_));
|
||||
} catch (std::out_of_range& e) {
|
||||
|
@ -69,15 +70,22 @@ FrameWrapper::startRendering()
|
|||
renderConnections_.stopped = QObject::connect(&avModel_,
|
||||
&AVModel::rendererStopped,
|
||||
this,
|
||||
&FrameWrapper::slotRenderingStopped);
|
||||
&FrameWrapper::slotRenderingStopped,
|
||||
Qt::DirectConnection);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
FrameWrapper::stopRendering()
|
||||
{
|
||||
isRendering_ = false;
|
||||
}
|
||||
|
||||
QImage*
|
||||
FrameWrapper::getFrame()
|
||||
{
|
||||
return image_.get();
|
||||
return isRendering_ ? image_.get() : nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -99,8 +107,6 @@ FrameWrapper::slotRenderingStarted(const QString& id)
|
|||
}
|
||||
|
||||
isRendering_ = true;
|
||||
|
||||
emit renderingStarted(id);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -140,7 +146,6 @@ FrameWrapper::slotFrameUpdated(const QString& id)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
emit frameUpdated(id);
|
||||
}
|
||||
|
||||
|
@ -150,37 +155,22 @@ FrameWrapper::slotRenderingStopped(const QString& id)
|
|||
if (id != id_) {
|
||||
return;
|
||||
}
|
||||
isRendering_ = false;
|
||||
|
||||
QObject::disconnect(renderConnections_.updated);
|
||||
QObject::disconnect(renderConnections_.stopped);
|
||||
|
||||
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();
|
||||
|
||||
isRendering_ = false;
|
||||
|
||||
emit renderingStopped(id);
|
||||
}
|
||||
|
||||
RenderManager::RenderManager(AVModel& avModel)
|
||||
: avModel_(avModel)
|
||||
{
|
||||
deviceListSize_ = avModel_.getDevices().size();
|
||||
connect(&avModel_, &lrc::api::AVModel::deviceEvent, this, &RenderManager::slotDeviceEvent);
|
||||
|
||||
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(),
|
||||
&FrameWrapper::frameUpdated,
|
||||
[this](const QString& id) {
|
||||
|
@ -219,37 +209,27 @@ RenderManager::getPreviewFrame()
|
|||
}
|
||||
|
||||
void
|
||||
RenderManager::stopPreviewing(bool async)
|
||||
RenderManager::stopPreviewing()
|
||||
{
|
||||
if (!previewFrameWrapper_->isRendering()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (async) {
|
||||
QtConcurrent::run([this] { avModel_.stopPreview(); });
|
||||
} else {
|
||||
avModel_.stopPreview();
|
||||
}
|
||||
previewFrameWrapper_->stopRendering();
|
||||
avModel_.stopPreview();
|
||||
}
|
||||
|
||||
void
|
||||
RenderManager::startPreviewing(bool force, bool async)
|
||||
RenderManager::startPreviewing(bool force)
|
||||
{
|
||||
if (previewFrameWrapper_->isRendering() && !force) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto restart = [this] {
|
||||
if (previewFrameWrapper_->isRendering()) {
|
||||
avModel_.stopPreview();
|
||||
}
|
||||
avModel_.startPreview();
|
||||
};
|
||||
if (async) {
|
||||
QtConcurrent::run(restart);
|
||||
} else {
|
||||
restart();
|
||||
if (previewFrameWrapper_->isRendering()) {
|
||||
avModel_.stopPreview();
|
||||
}
|
||||
avModel_.startPreview();
|
||||
}
|
||||
|
||||
QImage*
|
||||
|
@ -279,21 +259,11 @@ RenderManager::addDistantRenderer(const QString& id)
|
|||
/*
|
||||
* 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(),
|
||||
&FrameWrapper::frameUpdated,
|
||||
[this](const QString& id) {
|
||||
emit distantFrameUpdated(id);
|
||||
});
|
||||
distantConnectionMap_[id].stopped = QObject::connect(dfw.get(),
|
||||
&FrameWrapper::renderingStopped,
|
||||
[this](const QString& id) {
|
||||
emit distantRenderingStopped(id);
|
||||
});
|
||||
|
||||
/*
|
||||
* Connect FrameWrapper to avmodel.
|
||||
|
@ -319,7 +289,6 @@ RenderManager::removeDistantRenderer(const QString& id)
|
|||
if (dcIt != distantConnectionMap_.end()) {
|
||||
QObject::disconnect(dcIt->second.started);
|
||||
QObject::disconnect(dcIt->second.updated);
|
||||
QObject::disconnect(dcIt->second.stopped);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -327,48 +296,4 @@ RenderManager::removeDistantRenderer(const QString& id)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -61,6 +61,11 @@ public:
|
|||
*/
|
||||
bool startRendering();
|
||||
|
||||
/*
|
||||
* Locally disable frame access to this FrameWrapper
|
||||
*/
|
||||
void stopRendering();
|
||||
|
||||
/*
|
||||
* Get the most recently rendered frame as a QImage.
|
||||
* @return the rendered image of this object's id
|
||||
|
@ -73,11 +78,6 @@ public:
|
|||
bool isRendering();
|
||||
|
||||
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.
|
||||
* @param id of the renderer
|
||||
|
@ -180,14 +180,12 @@ public:
|
|||
/*
|
||||
* Start capturing and rendering preview frames.
|
||||
* @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.
|
||||
* @param async
|
||||
*/
|
||||
void stopPreviewing(bool async = true);
|
||||
void stopPreviewing();
|
||||
|
||||
/*
|
||||
* Get the most recently rendered distant frame for a given id
|
||||
|
@ -209,15 +207,6 @@ public:
|
|||
void removeDistantRenderer(const QString& id);
|
||||
|
||||
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.
|
||||
|
@ -229,11 +218,6 @@ signals:
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -244,23 +228,7 @@ signals:
|
|||
*/
|
||||
void distantRenderingStopped(const QString& id);
|
||||
|
||||
private slots:
|
||||
/*
|
||||
* Used to listen to AVModel::deviceEvent.
|
||||
*/
|
||||
void slotDeviceEvent();
|
||||
|
||||
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.
|
||||
*/
|
||||
|
@ -277,4 +245,3 @@ private:
|
|||
*/
|
||||
AVModel& avModel_;
|
||||
};
|
||||
Q_DECLARE_METATYPE(RenderManager*)
|
||||
|
|
|
@ -41,6 +41,8 @@ Rectangle {
|
|||
onVisibleChanged: {
|
||||
if(visible){
|
||||
setSelected(selectedMenu,true)
|
||||
} else {
|
||||
AccountAdapter.stopPreviewing()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,21 +53,20 @@ Rectangle {
|
|||
switch(sel) {
|
||||
case SettingsView.Account:
|
||||
pageIdCurrentAccountSettings.connectCurrentAccount()
|
||||
settingsViewRect.stopPreviewing()
|
||||
AccountAdapter.stopPreviewing()
|
||||
selectedMenu = sel
|
||||
pageIdCurrentAccountSettings.updateAccountInfoDisplayed()
|
||||
break
|
||||
case SettingsView.General:
|
||||
settingsViewRect.stopPreviewing()
|
||||
AccountAdapter.stopPreviewing()
|
||||
selectedMenu = sel
|
||||
break
|
||||
case SettingsView.Media:
|
||||
selectedMenu = sel
|
||||
settingsViewRect.stopPreviewing()
|
||||
avSettings.populateAVSettings()
|
||||
break
|
||||
case SettingsView.Plugin:
|
||||
settingsViewRect.stopPreviewing()
|
||||
AccountAdapter.stopPreviewing()
|
||||
selectedMenu = sel
|
||||
pluginSettings.populatePluginSettings()
|
||||
break
|
||||
|
@ -83,7 +84,7 @@ Rectangle {
|
|||
|
||||
// slots
|
||||
function leaveSettingsSlot(showMainView) {
|
||||
settingsViewRect.stopPreviewing()
|
||||
AccountAdapter.stopPreviewing()
|
||||
settingsViewRect.stopBooth()
|
||||
if (showMainView)
|
||||
settingsViewWindowNeedToShowMainViewWindow()
|
||||
|
@ -118,7 +119,6 @@ Rectangle {
|
|||
anchors.fill: root
|
||||
color: JamiTheme.secondaryBackgroundColor
|
||||
|
||||
signal stopPreviewing
|
||||
signal stopBooth
|
||||
|
||||
property bool isSIP: {
|
||||
|
|
|
@ -35,12 +35,6 @@ Rectangle {
|
|||
property int contentWidth: avSettingsColumnLayout.width
|
||||
property int preferredHeight: avSettingsColumnLayout.implicitHeight
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
videoSettings.stopPreviewing()
|
||||
}
|
||||
}
|
||||
|
||||
function populateAVSettings() {
|
||||
audioSettings.populateAudioSettings()
|
||||
videoSettings.populateVideoSettings()
|
||||
|
|
|
@ -41,9 +41,11 @@ RowLayout {
|
|||
|
||||
signal indexChanged
|
||||
|
||||
function setCurrentIndex(index) {
|
||||
function setCurrentIndex(index, emitIndexChanged = false) {
|
||||
comboBoxOfLayout.currentIndex = index
|
||||
modelIndex = index
|
||||
if (emitIndexChanged)
|
||||
indexChanged()
|
||||
}
|
||||
|
||||
function setEnabled(status) {
|
||||
|
|
|
@ -38,7 +38,7 @@ ColumnLayout {
|
|||
property int itemWidth
|
||||
|
||||
Connections {
|
||||
target: RenderManager
|
||||
target: AvAdapter
|
||||
enabled: root.visible
|
||||
|
||||
function onVideoDeviceListChanged() {
|
||||
|
@ -54,13 +54,9 @@ ColumnLayout {
|
|||
resolutionComboBoxSetting.setEnabled(count)
|
||||
fpsComboBoxSetting.setEnabled(count)
|
||||
|
||||
deviceComboBoxSetting.setCurrentIndex(deviceComboBoxSetting.comboModel.getCurrentSettingIndex())
|
||||
slotDeviceBoxCurrentIndexChanged(deviceComboBoxSetting.modelIndex)
|
||||
deviceComboBoxSetting.setCurrentIndex(
|
||||
deviceComboBoxSetting.comboModel.getCurrentSettingIndex(), true)
|
||||
hardwareAccelControl.checked = AVModel.getHardwareAcceleration()
|
||||
|
||||
try {
|
||||
startPreviewing(false)
|
||||
} catch (err2){ console.log("Start preview fail when populate video settings, exception: "+ err2.message) }
|
||||
}
|
||||
|
||||
function slotDeviceBoxCurrentIndexChanged(index) {
|
||||
|
@ -78,12 +74,12 @@ ColumnLayout {
|
|||
AVModel.setCurrentVideoCaptureDevice(deviceId)
|
||||
AVModel.setDefaultDevice(deviceId)
|
||||
setFormatListForCurrentDevice()
|
||||
startPreviewing(true)
|
||||
startPreviewing()
|
||||
} catch(err){ console.warn(err.message) }
|
||||
}
|
||||
|
||||
function startPreviewing(force = false, async = true) {
|
||||
AccountAdapter.startPreviewing(force, async)
|
||||
function startPreviewing(force = false) {
|
||||
AccountAdapter.startPreviewing(force)
|
||||
previewAvailable = true
|
||||
}
|
||||
|
||||
|
@ -94,15 +90,11 @@ ColumnLayout {
|
|||
|
||||
try {
|
||||
resolutionComboBoxSetting.comboModel.reset()
|
||||
resolutionComboBoxSetting.setCurrentIndex(resolutionComboBoxSetting.comboModel.getCurrentSettingIndex())
|
||||
slotFormatCurrentIndexChanged(resolutionComboBoxSetting.modelIndex, true)
|
||||
resolutionComboBoxSetting.setCurrentIndex(
|
||||
resolutionComboBoxSetting.comboModel.getCurrentSettingIndex(), true)
|
||||
} catch(err){ console.warn("Exception: " + err.message) }
|
||||
}
|
||||
|
||||
function stopPreviewing(async = true) {
|
||||
AccountAdapter.stopPreviewing(async)
|
||||
}
|
||||
|
||||
function slotFormatCurrentIndexChanged(index, isResolutionIndex) {
|
||||
var resolution
|
||||
var rate
|
||||
|
@ -111,7 +103,8 @@ ColumnLayout {
|
|||
resolutionComboBoxSetting.comboModel.index(index, 0),
|
||||
VideoFormatResolutionModel.Resolution)
|
||||
fpsComboBoxSetting.comboModel.currentResolution = resolution
|
||||
fpsComboBoxSetting.setCurrentIndex(fpsComboBoxSetting.comboModel.getCurrentSettingIndex())
|
||||
fpsComboBoxSetting.setCurrentIndex(
|
||||
fpsComboBoxSetting.comboModel.getCurrentSettingIndex(), true)
|
||||
rate = fpsComboBoxSetting.comboModel.data(
|
||||
fpsComboBoxSetting.comboModel.index(0, 0),
|
||||
VideoFormatFpsModel.FPS)
|
||||
|
@ -221,7 +214,7 @@ ColumnLayout {
|
|||
|
||||
onSwitchToggled: {
|
||||
AVModel.setHardwareAcceleration(checked)
|
||||
videoSettings.startPreviewing(true)
|
||||
startPreviewing(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -201,26 +201,6 @@ UtilsAdapter::setCurrentCall(const QString& accountId, const QString& convUid)
|
|||
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
|
||||
UtilsAdapter::hasCall(const QString& accountId)
|
||||
{
|
||||
|
|
|
@ -58,9 +58,6 @@ public:
|
|||
Q_INVOKABLE const QStringList getCurrAccList();
|
||||
Q_INVOKABLE int getAccountListSize();
|
||||
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 const QString getCallConvForAccount(const QString& accountId);
|
||||
Q_INVOKABLE const QString getCallId(const QString& accountId, const QString& convUid);
|
||||
|
|
Loading…
Add table
Reference in a new issue