Fix H264 codec not loading

This commit is contained in:
Christophe Deschamps 2024-12-10 22:01:14 +01:00
parent 04e270e699
commit 4d426962d2
7 changed files with 161 additions and 26 deletions

View file

@ -35,6 +35,7 @@ QSharedPointer<DownloadablePayloadTypeCore> DownloadablePayloadTypeCore::create(
auto sharedPointer = QSharedPointer<DownloadablePayloadTypeCore>(
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<DownloadablePayloadTypeModel>();
mFamily = family;
mMimeType = mimeType;
@ -63,6 +65,25 @@ DownloadablePayloadTypeCore::~DownloadablePayloadTypeCore() {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
}
void DownloadablePayloadTypeCore::setSelf(QSharedPointer<DownloadablePayloadTypeCore> me) {
mDownloadablePayloadTypeModelConnection =
QSharedPointer<SafeConnection<DownloadablePayloadTypeCore, DownloadablePayloadTypeModel>>(
new SafeConnection<DownloadablePayloadTypeCore, DownloadablePayloadTypeModel>(
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();

View file

@ -22,6 +22,7 @@
#define DOWNLOADABLE_PAYLOAD_TYPE_CORE_H_
#include "PayloadTypeCore.hpp"
#include "model/payload-type/DownloadablePayloadTypeModel.hpp"
#include "tool/AbstractObject.hpp"
#include <QObject>
#include <QSharedPointer>
@ -52,11 +53,12 @@ public:
void setSelf(QSharedPointer<DownloadablePayloadTypeCore> 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<DownloadablePayloadTypeModel> mDownloadablePayloadTypeModel;
QSharedPointer<SafeConnection<DownloadablePayloadTypeCore, DownloadablePayloadTypeModel>>
mDownloadablePayloadTypeModelConnection;
DECLARE_ABSTRACT_OBJECT
};
Q_DECLARE_METATYPE(DownloadablePayloadTypeCore *)

View file

@ -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
)

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <QLibrary>
#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;
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef DOWNLOADABLE_PAYLOAD_TYPE_MODEL_H_
#define DOWNLOADABLE_PAYLOAD_TYPE_MODEL_H_
#include "tool/AbstractObject.hpp"
#include <QObject>
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

View file

@ -310,18 +310,21 @@ bool ToolModel::friendIsInFriendList(const std::shared_ptr<linphone::FriendList>
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)
}

View file

@ -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()
})