H264 downloadable codec - code adjustments + fix advanced settings

This commit is contained in:
Christophe Deschamps 2024-11-12 16:32:33 +00:00
parent 425751413d
commit d11b3bce3d
13 changed files with 81 additions and 111 deletions

View file

@ -81,6 +81,7 @@
#include "core/variant/VariantList.hpp"
#include "core/videoSource/VideoSourceDescriptorGui.hpp"
#include "model/object/VariantObject.hpp"
#include "model/tool/ToolModel.hpp"
#include "tool/Constants.hpp"
#include "tool/EnumsToString.hpp"
#include "tool/Utils.hpp"
@ -434,10 +435,10 @@ void App::initCore() {
mLinphoneThread->getThreadId(),
[this]() mutable {
lInfo() << log().arg("Updating downloaded codec files");
Utils::updateCodecs(); // removing codec updates suffic (.in) before the core is created.
ToolModel::updateCodecs(); // removing codec updates suffic (.in) before the core is created.
lInfo() << log().arg("Starting Core");
CoreModel::getInstance()->start();
Utils::loadDownloadedCodecs();
ToolModel::loadDownloadedCodecs();
auto coreStarted = CoreModel::getInstance()->getCore()->getGlobalState() == linphone::GlobalState::On;
lDebug() << log().arg("Creating SettingsModel");
SettingsModel::create();

View file

@ -62,7 +62,6 @@ private:
QString mDownloadUrl;
QString mInstallName;
QString mCheckSum;
bool mInstalled;
QString mVersion;
DECLARE_ABSTRACT_OBJECT

View file

@ -64,6 +64,6 @@ QString PayloadTypeCore::getMimeType() {
return mMimeType;
}
bool PayloadTypeCore::getDownloadable() {
bool PayloadTypeCore::isDownloadable() {
return mDownloadable;
}

View file

@ -37,7 +37,7 @@ class PayloadTypeCore : public QObject, public AbstractObject {
DECLARE_CORE_MEMBER(QString, recvFmtp, RecvFmtp)
public:
enum Family { None, Audio, Video, Text };
enum Family { Audio, Video, Text };
static QSharedPointer<PayloadTypeCore> create(Family family,
const std::shared_ptr<linphone::PayloadType> &payloadType);
@ -48,7 +48,7 @@ public:
void setSelf(QSharedPointer<PayloadTypeCore> me);
Family getFamily();
bool getDownloadable();
bool isDownloadable();
QString getMimeType();
protected:

View file

@ -24,6 +24,7 @@
#include "core/App.hpp"
#include "core/path/Paths.hpp"
#include "model/object/VariantObject.hpp"
#include "model/tool/ToolModel.hpp"
#include <QSharedPointer>
#include <linphone++/linphone.hh>
@ -56,7 +57,7 @@ void PayloadTypeList::setSelf(QSharedPointer<PayloadTypeList> me) {
QList<QSharedPointer<PayloadTypeCore>> *payloadTypes = new QList<QSharedPointer<PayloadTypeCore>>();
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
Utils::loadDownloadedCodecs();
ToolModel::loadDownloadedCodecs();
// Audio
for (auto payloadType : CoreModel::getInstance()->getCore()->getAudioPayloadTypes()) {

View file

@ -32,33 +32,16 @@ PayloadTypeProxy::PayloadTypeProxy(QObject *parent) : LimitProxy(parent) {
PayloadTypeProxy::~PayloadTypeProxy() {
}
PayloadTypeCore::Family PayloadTypeProxy::getFamily() const {
return dynamic_cast<SortFilterList *>(sourceModel())->mFamily;
}
void PayloadTypeProxy::setFamily(PayloadTypeCore::Family data) {
auto list = dynamic_cast<SortFilterList *>(sourceModel());
if (list->mFamily != data) {
list->mFamily = data;
familyChanged();
}
}
bool PayloadTypeProxy::isDownloadable() const {
return dynamic_cast<SortFilterList *>(sourceModel())->mDownloadable;
}
void PayloadTypeProxy::setDownloadable(bool data) {
auto list = dynamic_cast<SortFilterList *>(sourceModel());
if (list->mDownloadable != data) {
list->mDownloadable = data;
downloadableChanged();
}
}
bool PayloadTypeProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
auto payload = qobject_cast<PayloadTypeList *>(sourceModel())->getAt<PayloadTypeCore>(sourceRow);
return payload->getFamily() == mFamily && payload->getDownloadable() == mDownloadable;
int payloadFlag = PayloadTypeProxyFiltering::All;
payloadFlag += payload->isDownloadable() ? PayloadTypeProxyFiltering::Downloadable
: PayloadTypeProxyFiltering::NotDownloadable;
auto family = payload->getFamily();
payloadFlag += family == PayloadTypeCore::Family::Audio ? PayloadTypeProxyFiltering::Audio : 0;
payloadFlag += family == PayloadTypeCore::Family::Video ? PayloadTypeProxyFiltering::Video : 0;
payloadFlag += family == PayloadTypeCore::Family::Text ? PayloadTypeProxyFiltering::Text : 0;
return mFilterType == payloadFlag;
}
bool PayloadTypeProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {

View file

@ -30,26 +30,24 @@
class PayloadTypeProxy : public LimitProxy, public AbstractObject {
Q_OBJECT
Q_PROPERTY(PayloadTypeCore::Family family READ getFamily WRITE setFamily NOTIFY familyChanged)
Q_PROPERTY(bool downloadable READ isDownloadable WRITE setDownloadable NOTIFY downloadableChanged)
public:
DECLARE_SORTFILTER_CLASS(PayloadTypeCore::Family mFamily; bool mDownloadable;)
enum PayloadTypeProxyFiltering {
All = 0,
Audio = 2,
Video = 4,
Text = 8,
Downloadable = 16,
NotDownloadable = 32
};
Q_ENUMS(PayloadTypeProxyFiltering)
DECLARE_SORTFILTER_CLASS()
Q_INVOKABLE void reload();
PayloadTypeProxy(QObject *parent = Q_NULLPTR);
~PayloadTypeProxy();
PayloadTypeCore::Family getFamily() const;
void setFamily(PayloadTypeCore::Family data);
bool isDownloadable() const;
void setDownloadable(bool data);
signals:
void familyChanged();
void downloadableChanged();
protected:
QSharedPointer<PayloadTypeList> mPayloadTypeList;

View file

@ -24,6 +24,8 @@
#include "model/core/CoreModel.hpp"
#include "tool/Utils.hpp"
#include <QDebug>
#include <QDirIterator>
#include <QLibrary>
#include <QTest>
DEFINE_ABSTRACT_OBJECT(ToolModel)
@ -304,3 +306,47 @@ bool ToolModel::friendIsInFriendList(const std::shared_ptr<linphone::FriendList>
}
return false;
}
// Load downloaded codecs like OpenH264 (needs to be after core is created and has loaded its plugins, as
// reloadMsPlugins modifies plugin path for the factory)
void ToolModel::loadDownloadedCodecs() {
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
#if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
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);
else qInfo() << QStringLiteral("Loaded `%1` symbols...").arg(filename);
}
}
CoreModel::getInstance()->getCore()->reloadMsPlugins("");
#endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
}
// Removes .in suffix from downloaded updates.
// Updates are downloaded with .in suffix as they can't overwrite already loaded plugin
// they are loaded at next app startup.
void ToolModel::updateCodecs() {
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
#if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
static const QString codecSuffix = QStringLiteral(".%1").arg(Constants::LibraryExtension);
QDirIterator it(Paths::getCodecsDirPath());
while (it.hasNext()) {
QFileInfo info(it.next());
if (info.suffix() == QLatin1String("in")) {
QString codecName = info.completeBaseName();
if (codecName.endsWith(codecSuffix)) {
QString codecPath = info.dir().path() + QDir::separator() + codecName;
QFile::remove(codecPath);
QFile::rename(info.filePath(), codecPath);
}
}
}
#endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
}

View file

@ -65,6 +65,8 @@ public:
static bool friendIsInFriendList(const std::shared_ptr<linphone::FriendList> &friendList,
const std::shared_ptr<linphone::Friend> &f);
static void loadDownloadedCodecs();
static void updateCodecs();
private:
DECLARE_ABSTRACT_OBJECT

View file

@ -36,10 +36,8 @@
#include <QClipboard>
#include <QCryptographicHash>
#include <QDesktopServices>
#include <QDirIterator>
#include <QHostAddress>
#include <QImageReader>
#include <QLibrary>
#include <QQuickWindow>
#include <QRandomGenerator>
#include <QRegularExpression>
@ -1439,47 +1437,3 @@ void Utils::checkDownloadedCodecsUpdates() {
if (codec->shouldDownloadUpdate()) codec->downloadAndExtract(true);
}
}
// Load downloaded codecs like OpenH264 (needs to be after core is created and has loaded its plugins, as
// reloadMsPlugins modifies plugin path for the factory)
void Utils::loadDownloadedCodecs() {
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
#if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
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);
else qInfo() << QStringLiteral("Loaded `%1` symbols...").arg(filename);
}
}
CoreModel::getInstance()->getCore()->reloadMsPlugins("");
#endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
}
// Removes .in suffix from downloaded updates.
// Updates are downloaded with .in suffix as they can't overwrite already loaded plugin
// they are loaded at next app startup.
void Utils::updateCodecs() {
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
#if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
static const QString codecSuffix = QStringLiteral(".%1").arg(Constants::LibraryExtension);
QDirIterator it(Paths::getCodecsDirPath());
while (it.hasNext()) {
QFileInfo info(it.next());
if (info.suffix() == QLatin1String("in")) {
QString codecName = info.completeBaseName();
if (codecName.endsWith(codecSuffix)) {
QString codecPath = info.dir().path() + QDir::separator() + codecName;
QFile::remove(codecPath);
QFile::rename(info.filePath(), codecPath);
}
}
}
#endif // if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
}

View file

@ -140,8 +140,6 @@ public:
static QString computeUserAgent();
static QList<QSharedPointer<DownloadablePayloadTypeCore>> getDownloadableVideoPayloadTypes();
static void checkDownloadedCodecsUpdates();
static void loadDownloadedCodecs();
static void updateCodecs();
static inline QString coreStringToAppString(const std::string &str) {
if (Constants::LinphoneLocaleEncoding == QString("UTF-8")) return QString::fromStdString(str);

View file

@ -100,7 +100,7 @@ AbstractSettingsLayout {
Layout.leftMargin: 64 * DefaultStyle.dp
Repeater {
model: PayloadTypeProxy {
family: PayloadTypeCore.Audio
filterType: PayloadTypeProxy.Audio | PayloadTypeProxy.NotDownloadable
}
SwitchSetting {
Layout.fillWidth: true
@ -151,7 +151,7 @@ AbstractSettingsLayout {
Repeater {
model: PayloadTypeProxy {
id: videoPayloadTypeProxy
family: PayloadTypeCore.Video
filterType: PayloadTypeProxy.Video | PayloadTypeProxy.NotDownloadable
}
SwitchSetting {
Layout.fillWidth: true
@ -164,26 +164,15 @@ AbstractSettingsLayout {
Repeater {
model: PayloadTypeProxy {
id: downloadableVideoPayloadTypeProxy
family: PayloadTypeCore.Video
downloadable: true
filterType: PayloadTypeProxy.Video | PayloadTypeProxy.Downloadable
}
SwitchSetting {
Layout.fillWidth: true
titleText: Utils.capitalizeFirstLetter(modelData.core.mimeType)
subTitleText: modelData.core.encoderDescription
onCheckChanged: function(checked) {
onCheckedChanged: function(checked) {
if (checked)
UtilsCpp.getMainWindow().showConfirmationLambdaPopup("",
qsTr("Installation"),
qsTr("Télécharger le codec ") + Utils.capitalizeFirstLetter(modelData.core.mimeType) + " ("+modelData.core.encoderDescription+")"+" ?",
function (confirmed) {
if (confirmed) {
UtilsCpp.getMainWindow().showLoadingPopup(qsTr("Téléchargement en cours ..."))
modelData.core.downloadAndExtract()
} else
setChecked(false)
}
)
Utils.openCodecOnlineInstallerDialog(mainWindow, modelData.core)
}
}
}

View file

@ -232,8 +232,7 @@ AbstractWindow {
// H264 Cisco codec download
PayloadTypeProxy {
id: downloadableVideoPayloadTypeProxy
family: PayloadTypeCore.Video
downloadable: true
filterType: PayloadTypeProxy.Video | PayloadTypeProxy.Downloadable
}
Repeater {
id: codecDownloader