From 4d426962d2f371b0a2505ac0b20a3c7e22da1ed2 Mon Sep 17 00:00:00 2001 From: Christophe Deschamps Date: Tue, 10 Dec 2024 22:01:14 +0100 Subject: [PATCH] Fix H264 codec not loading --- .../DownloadablePayloadTypeCore.cpp | 54 ++++++++++++------ .../DownloadablePayloadTypeCore.hpp | 8 ++- Linphone/model/CMakeLists.txt | 1 + .../DownloadablePayloadTypeModel.cpp | 55 +++++++++++++++++++ .../DownloadablePayloadTypeModel.hpp | 42 ++++++++++++++ Linphone/model/tool/ToolModel.cpp | 9 ++- Linphone/view/Control/Tool/Helper/utils.js | 18 ++++-- 7 files changed, 161 insertions(+), 26 deletions(-) create mode 100644 Linphone/model/payload-type/DownloadablePayloadTypeModel.cpp create mode 100644 Linphone/model/payload-type/DownloadablePayloadTypeModel.hpp diff --git a/Linphone/core/payload-type/DownloadablePayloadTypeCore.cpp b/Linphone/core/payload-type/DownloadablePayloadTypeCore.cpp index bd3019bcb..7b8b70a3f 100644 --- a/Linphone/core/payload-type/DownloadablePayloadTypeCore.cpp +++ b/Linphone/core/payload-type/DownloadablePayloadTypeCore.cpp @@ -35,6 +35,7 @@ QSharedPointer DownloadablePayloadTypeCore::create( auto sharedPointer = QSharedPointer( new DownloadablePayloadTypeCore(family, mimeType, encoderDescription, downloadUrl, installName, checkSum), &QObject::deleteLater); + sharedPointer->setSelf(sharedPointer); sharedPointer->moveToThread(App::getInstance()->thread()); return sharedPointer; } @@ -47,6 +48,7 @@ DownloadablePayloadTypeCore::DownloadablePayloadTypeCore(PayloadTypeCore::Family const QString &checkSum) : PayloadTypeCore() { App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); + mDownloadablePayloadTypeModel = Utils::makeQObject_ptr(); mFamily = family; mMimeType = mimeType; @@ -63,6 +65,25 @@ DownloadablePayloadTypeCore::~DownloadablePayloadTypeCore() { mustBeInMainThread(log().arg(Q_FUNC_INFO)); } +void DownloadablePayloadTypeCore::setSelf(QSharedPointer me) { + mDownloadablePayloadTypeModelConnection = + QSharedPointer>( + new SafeConnection( + me, mDownloadablePayloadTypeModel), + &QObject::deleteLater); + + mDownloadablePayloadTypeModelConnection->makeConnectToCore( + &DownloadablePayloadTypeCore::extractSuccess, [this](QString filePath) { + mDownloadablePayloadTypeModelConnection->invokeToModel( + [this, filePath]() { mDownloadablePayloadTypeModel->loadLibrary(filePath); }); + }); + + mDownloadablePayloadTypeModelConnection->makeConnectToModel( + &DownloadablePayloadTypeModel::loaded, [this](bool success) { + mDownloadablePayloadTypeModelConnection->invokeToCore([this, success]() { emit loaded(success); }); + }); +} + void DownloadablePayloadTypeCore::downloadAndExtract(bool isUpdate) { lInfo() << log().arg("Downloading `%1` codec...").arg(mMimeType); auto codecsFolder = Paths::getCodecsDirPath(); @@ -95,22 +116,23 @@ void DownloadablePayloadTypeCore::downloadAndExtract(bool isUpdate) { emit downloadError(); }); - QObject::connect(fileExtractor, &FileExtractor::extractFinished, - [this, fileDownloader, fileExtractor, versionFilePath, downloadUrl = mDownloadUrl]() { - QFile versionFile(versionFilePath); - if (!versionFile.open(QIODevice::WriteOnly)) { - lWarning() << log().arg("Unable to write codec version in: `%1`.").arg(versionFilePath); - emit extractError(); - } else if (versionFile.write(Utils::appStringToCoreString(downloadUrl).c_str(), - downloadUrl.length()) == -1) { - fileExtractor->remove(); - versionFile.close(); - versionFile.remove(); - emit extractError(); - } else emit success(); - fileDownloader->remove(); - fileDownloader->deleteLater(); - }); + QObject::connect( + fileExtractor, &FileExtractor::extractFinished, + [this, fileDownloader, fileExtractor, versionFilePath, downloadUrl = mDownloadUrl]() { + QFile versionFile(versionFilePath); + if (!versionFile.open(QIODevice::WriteOnly)) { + lWarning() << log().arg("Unable to write codec version in: `%1`.").arg(versionFilePath); + emit extractError(); + } else if (versionFile.write(Utils::appStringToCoreString(downloadUrl).c_str(), downloadUrl.length()) == + -1) { + fileExtractor->remove(); + versionFile.close(); + versionFile.remove(); + emit extractError(); + } else emit extractSuccess(fileExtractor->getExtractFolder() + "/" + fileExtractor->getExtractName()); + fileDownloader->remove(); + fileDownloader->deleteLater(); + }); QObject::connect(fileExtractor, &FileExtractor::extractFailed, [this, fileDownloader]() { fileDownloader->remove(); diff --git a/Linphone/core/payload-type/DownloadablePayloadTypeCore.hpp b/Linphone/core/payload-type/DownloadablePayloadTypeCore.hpp index 8f4820850..0ac82a3be 100644 --- a/Linphone/core/payload-type/DownloadablePayloadTypeCore.hpp +++ b/Linphone/core/payload-type/DownloadablePayloadTypeCore.hpp @@ -22,6 +22,7 @@ #define DOWNLOADABLE_PAYLOAD_TYPE_CORE_H_ #include "PayloadTypeCore.hpp" +#include "model/payload-type/DownloadablePayloadTypeModel.hpp" #include "tool/AbstractObject.hpp" #include #include @@ -52,11 +53,12 @@ public: void setSelf(QSharedPointer me); signals: - void success(); + void extractSuccess(QString filePath); void downloadError(); void extractError(); void installedChanged(); void versionChanged(); + void loaded(bool success); private: QString mDownloadUrl; @@ -64,6 +66,10 @@ private: QString mCheckSum; QString mVersion; + std::shared_ptr mDownloadablePayloadTypeModel; + QSharedPointer> + mDownloadablePayloadTypeModelConnection; + DECLARE_ABSTRACT_OBJECT }; Q_DECLARE_METATYPE(DownloadablePayloadTypeCore *) diff --git a/Linphone/model/CMakeLists.txt b/Linphone/model/CMakeLists.txt index e6bb79d24..f09f9486a 100644 --- a/Linphone/model/CMakeLists.txt +++ b/Linphone/model/CMakeLists.txt @@ -44,6 +44,7 @@ list(APPEND _LINPHONEAPP_SOURCES model/address-books/ldap/LdapModel.cpp model/address-books/carddav/CarddavModel.cpp model/payload-type/PayloadTypeModel.cpp + model/payload-type/DownloadablePayloadTypeModel.cpp ) diff --git a/Linphone/model/payload-type/DownloadablePayloadTypeModel.cpp b/Linphone/model/payload-type/DownloadablePayloadTypeModel.cpp new file mode 100644 index 000000000..4a6f8c306 --- /dev/null +++ b/Linphone/model/payload-type/DownloadablePayloadTypeModel.cpp @@ -0,0 +1,55 @@ +/* + * 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 "DownloadablePayloadTypeModel.hpp" +#include "model/core/CoreModel.hpp" +#include "tool/Utils.hpp" + +DEFINE_ABSTRACT_OBJECT(DownloadablePayloadTypeModel) + +DownloadablePayloadTypeModel::DownloadablePayloadTypeModel(QObject *parent) { + mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); +} + +DownloadablePayloadTypeModel::~DownloadablePayloadTypeModel() { + mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); +} + +void DownloadablePayloadTypeModel::loadLibrary(QString filename) { + mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); + lInfo() << log().arg("Loading library:") << filename; + if (QLibrary::isLibrary(filename)) { + auto library = QLibrary(filename); + if (!library.load()) { + lWarning() << log().arg("Failed loading library:") << filename << " error:" << library.errorString(); + emit loaded(false); + } else { + lInfo() << log().arg("Successfully loaded library:") << filename; + CoreModel::getInstance()->getCore()->reloadMsPlugins(""); + emit loaded(true); + } + } else { + lWarning() << log().arg("Failed loading library (not a library file):") << filename; + emit loaded(false); + } + lInfo() << log().arg("Finished Loading library:") << filename; +} diff --git a/Linphone/model/payload-type/DownloadablePayloadTypeModel.hpp b/Linphone/model/payload-type/DownloadablePayloadTypeModel.hpp new file mode 100644 index 000000000..322942f9e --- /dev/null +++ b/Linphone/model/payload-type/DownloadablePayloadTypeModel.hpp @@ -0,0 +1,42 @@ +/* + * 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 . + */ + +#ifndef DOWNLOADABLE_PAYLOAD_TYPE_MODEL_H_ +#define DOWNLOADABLE_PAYLOAD_TYPE_MODEL_H_ + +#include "tool/AbstractObject.hpp" +#include + +class DownloadablePayloadTypeModel : public QObject, public AbstractObject { + Q_OBJECT + +public: + DownloadablePayloadTypeModel(QObject *parent = nullptr); + ~DownloadablePayloadTypeModel(); + void loadLibrary(QString filename); + +signals: + void loaded(bool success); + +private: + DECLARE_ABSTRACT_OBJECT +}; + +#endif diff --git a/Linphone/model/tool/ToolModel.cpp b/Linphone/model/tool/ToolModel.cpp index 20e92379b..eccbc16c2 100644 --- a/Linphone/model/tool/ToolModel.cpp +++ b/Linphone/model/tool/ToolModel.cpp @@ -310,18 +310,21 @@ bool ToolModel::friendIsInFriendList(const std::shared_ptr void ToolModel::loadDownloadedCodecs() { mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO)); #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) + qInfo() << QStringLiteral("Loading downloaded codecs in folder %1...").arg(Paths::getCodecsDirPath()); QDirIterator it(Paths::getCodecsDirPath()); while (it.hasNext()) { QFileInfo info(it.next()); const QString filename(info.fileName()); if (QLibrary::isLibrary(filename)) { qInfo() << QStringLiteral("Loading `%1` symbols...").arg(filename); - if (!QLibrary(info.filePath()).load()) // lib.load()) - qWarning() << QStringLiteral("Failed to load `%1` symbols.").arg(filename); + auto library = QLibrary(info.filePath()); + if (!library.load()) // lib.load()) + qWarning() << QStringLiteral("Failed to load `%1` symbols.").arg(filename) << library.errorString(); else qInfo() << QStringLiteral("Loaded `%1` symbols...").arg(filename); - } + } else qWarning() << QStringLiteral("Found codec file `%1` that is not a library").arg(filename); } CoreModel::getInstance()->getCore()->reloadMsPlugins(""); + qInfo() << QStringLiteral("Finished loading downloaded codecs."); #endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN) } diff --git a/Linphone/view/Control/Tool/Helper/utils.js b/Linphone/view/Control/Tool/Helper/utils.js index cdae2e502..1b8ab1754 100644 --- a/Linphone/view/Control/Tool/Helper/utils.js +++ b/Linphone/view/Control/Tool/Helper/utils.js @@ -690,21 +690,27 @@ function openCodecOnlineInstallerDialog (mainWindow, coreObject, cancelCallBack, qsTr("Télécharger le codec ") + capitalizeFirstLetter(coreObject.mimeType) + " ("+coreObject.encoderDescription+")"+" ?", function (confirmed) { if (confirmed) { - coreObject.success.connect(function() { + coreObject.loaded.connect(function(success) { mainWindow.closeLoadingPopup() - mainWindow.showInformationPopup(qsTr("Succès"), qsTr("Le codec a été téléchargé avec succès."), true) - if (successCallBack) - successCallBack() + if (success) { + mainWindow.showInformationPopup(qsTr("Succès"), qsTr("Le codec a été installé avec succès."), true) + if (successCallBack) + successCallBack() + } else { + mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être installé."), false) + if (errorCallBack) + errorCallBack() + } }) coreObject.extractError.connect(function() { mainWindow.closeLoadingPopup() - mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être sauvegardé."), true) + mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être sauvegardé."), false) if (errorCallBack) errorCallBack() }) coreObject.downloadError.connect(function() { mainWindow.closeLoadingPopup() - mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être téléchargé."), true) + mainWindow.showInformationPopup(qsTr("Erreur"), qsTr("Le codec n'a pas pu être téléchargé."), false) if (errorCallBack) errorCallBack() })