/* * Copyright (c) 2010-2024 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * 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 . */ #include #include #include #include #include "../App.hpp" #include "PreviewManager.hpp" #include "tool/Utils.hpp" DEFINE_ABSTRACT_OBJECT(PreviewManager) // ============================================================================= PreviewManager *PreviewManager::gInstance = nullptr; PreviewManager::PreviewManager(QObject *parent) : QObject(parent) { } PreviewManager::~PreviewManager() { } PreviewManager *PreviewManager::getInstance() { if (gInstance) return gInstance; else { gInstance = new PreviewManager(); return gInstance; } } // Create a Renderer from SDK preview QQuickFramebufferObject::Renderer *PreviewManager::subscribe(const CameraGui *candidate) { QQuickFramebufferObject::Renderer *renderer = nullptr; mCounterMutex.lock(); if (mCandidates.size() == 0) { activate(); } auto itCandidate = std::find_if(mCandidates.begin(), mCandidates.end(), [candidate](const QPair &item) { return item.first == candidate; }); if (itCandidate == mCandidates.end()) { connect(candidate, &QObject::destroyed, this, qOverload(&PreviewManager::unsubscribe)); mCandidates.append({candidate, nullptr}); itCandidate = mCandidates.end() - 1; lDebug() << log().arg("Subscribing New") << itCandidate->first->getQmlName(); } else { lDebug() << log().arg("Resubscribing") << itCandidate->first->getQmlName(); } App::postModelBlock([&renderer, isFirst = (itCandidate == mCandidates.begin()), name = itCandidate->first->getQmlName()]() { renderer = (QQuickFramebufferObject::Renderer *)CoreModel::getInstance()->getCore()->createNativePreviewWindowId(); if (!renderer) { // TODO debug renderer = (QQuickFramebufferObject::Renderer *)CoreModel::getInstance()->getCore()->createNativePreviewWindowId(); } if (isFirst) { lDebug() << "[PreviewManager] " << name << " Set Native Preview Id with " << renderer; CoreModel::getInstance()->getCore()->setNativePreviewWindowId(renderer); } }); itCandidate->second = renderer; mCounterMutex.unlock(); return renderer; } void PreviewManager::unsubscribe(const CameraGui *candidate) { // If nullptr, Use of sender() mCounterMutex.lock(); auto itCandidate = std::find_if(mCandidates.begin(), mCandidates.end(), [candidate = (candidate ? candidate : sender())]( const QPair &item) { return item.first == candidate; }); if (itCandidate != mCandidates.end()) { lDebug() << log().arg("Unsubscribing") << itCandidate->first->getQmlName(); disconnect(candidate, nullptr, this, nullptr); if (mCandidates.size() == 1) { mCandidates.erase(itCandidate); deactivate(); } else if (mCandidates.begin() == itCandidate) { mCandidates.erase(itCandidate); lDebug() << log().arg("Update") << mCandidates.first().first->getQmlName(); auto renderer = mCandidates.first().second; if (renderer) App::postModelBlock([renderer = mCandidates.first().second]() { CoreModel::getInstance()->getCore()->setNativePreviewWindowId(renderer); }); } else { mCandidates.erase(itCandidate); } } mCounterMutex.unlock(); } void PreviewManager::unsubscribe(QObject *sender) { unsubscribe(dynamic_cast(sender)); } void PreviewManager::activate() { App::postModelBlock([]() { lDebug() << "[PreviewManager] Activation"; CoreModel::getInstance()->getCore()->enableVideoPreview(true); CoreModel::getInstance()->getCore()->iterate(); }); } void PreviewManager::deactivate() { App::postModelBlock([]() { lDebug() << "[PreviewManager] Deactivation"; CoreModel::getInstance()->getCore()->enableVideoPreview(false); CoreModel::getInstance()->getCore()->iterate(); }); }