From 9327bc494fe2df18b4e2043b324aa8c5b1127137 Mon Sep 17 00:00:00 2001 From: "danmei.chen" Date: Tue, 20 Mar 2018 16:05:35 +0100 Subject: [PATCH] openh264: rename extractFile and store version of lib videoCodec: rename codec after installation and update codec when there is new version --- src/components/codecs/AbstractCodecsModel.cpp | 2 + src/components/codecs/AbstractCodecsModel.hpp | 2 +- src/components/codecs/VideoCodecsModel.cpp | 64 ++++++++++++++++++- src/components/codecs/VideoCodecsModel.hpp | 12 +++- src/components/file/FileDownloader.cpp | 21 +++++- src/components/file/FileDownloader.hpp | 9 ++- src/components/file/FileExtractor.cpp | 16 ++++- src/components/file/FileExtractor.hpp | 6 +- .../Linphone/Dialog/OnlineInstallerDialog.qml | 14 +++- ui/scripts/LinphoneUtils/linphone-utils.js | 1 + 10 files changed, 134 insertions(+), 13 deletions(-) diff --git a/src/components/codecs/AbstractCodecsModel.cpp b/src/components/codecs/AbstractCodecsModel.cpp index a35514c20..3ab0e893d 100644 --- a/src/components/codecs/AbstractCodecsModel.cpp +++ b/src/components/codecs/AbstractCodecsModel.cpp @@ -179,12 +179,14 @@ void AbstractCodecsModel::addCodec (shared_ptr &codec) { void AbstractCodecsModel::addDownloadableCodec ( const QString &mime, + const QString &fileName, const QString &downloadUrl, const QString &encoderDescription ) { QVariantMap map; map["mime"] = mime; + map["fileName"] = fileName; map["downloadUrl"] = downloadUrl; map["encoderDescription"] = encoderDescription; diff --git a/src/components/codecs/AbstractCodecsModel.hpp b/src/components/codecs/AbstractCodecsModel.hpp index 73cf843f6..d5ad9daab 100644 --- a/src/components/codecs/AbstractCodecsModel.hpp +++ b/src/components/codecs/AbstractCodecsModel.hpp @@ -67,7 +67,7 @@ protected: ) override; void addCodec (std::shared_ptr &codec); - void addDownloadableCodec (const QString &mime, const QString &downloadUrl, const QString &encoderDescription); + void addDownloadableCodec (const QString &mime, const QString &fileName, const QString &downloadUrl, const QString &encoderDescription); QString getCodecsFolder () const; diff --git a/src/components/codecs/VideoCodecsModel.cpp b/src/components/codecs/VideoCodecsModel.cpp index 6fa8fa367..dac88a72f 100644 --- a/src/components/codecs/VideoCodecsModel.cpp +++ b/src/components/codecs/VideoCodecsModel.cpp @@ -35,6 +35,7 @@ using namespace std; namespace { + constexpr char cH264FileName[] = "openh264"; constexpr char cH264Description[] = "Provided by CISCO SYSTEM,INC"; #ifdef Q_OS_LINUX @@ -56,8 +57,57 @@ namespace { VideoCodecsModel::VideoCodecsModel (QObject *parent) : AbstractCodecsModel(parent) { load(); + + // update codec if there is a new version + #if defined(Q_OS_LINUX) || defined(Q_OS_WIN) + QString codecsFolder = Utils::coreStringToAppString(Paths::getCodecsDirPath()); + QString filePath = QDir::cleanPath(codecsFolder) + QDir::separator() + cH264FileName + ".txt"; + + if(updateCodecVersion(filePath, cPluginUrlH264)) { + mFileDownloader = new FileDownloader(); + mFileDownloader->setUrl(QUrl(cPluginUrlH264)); + mFileDownloader->setDownloadFolder(codecsFolder); + mFileExtractor = new FileExtractor(); + mFileExtractor->setExtractFolder(codecsFolder); + + mFileDownloader->download(); + QObject::connect(mFileDownloader, &FileDownloader::downloadFinished, this, &VideoCodecsModel::extract); + QObject::connect(mFileDownloader, &FileDownloader::downloadFailed, this, &VideoCodecsModel::installFileFailed); + QObject::connect(mFileExtractor, &FileExtractor::extractFinished, this, &VideoCodecsModel::endInstallFile); + QObject::connect(mFileExtractor, &FileExtractor::extractFailed, this, &VideoCodecsModel::installFileFailed); + } + #endif } +VideoCodecsModel::~VideoCodecsModel () { + qInfo() << QStringLiteral("Delete VideoCodecsModel"); + + if (mFileDownloader) mFileDownloader = nullptr; + + if (mFileExtractor) mFileExtractor = nullptr; +} + +bool VideoCodecsModel::updateCodecVersion(const QString &filePath, const QString &newVersion) { + QFile versionFile(filePath); + + if (!versionFile.exists()) return false; + if (!versionFile.open(QIODevice::ReadOnly)) { + qWarning() << QStringLiteral("Unable to read version from file."); + return false; + } + QString version; + QTextStream s1(&versionFile); + version.append(s1.readAll()); + versionFile.close(); + + return QString::compare(newVersion, version, Qt::CaseInsensitive)>0; +} + +void VideoCodecsModel::installFileFailed() { + qWarning() << QStringLiteral("Unable to install codec `%1` .").arg(cH264FileName); +} + + void VideoCodecsModel::updateCodecs (list> &codecs) { CoreManager::getInstance()->getCore()->setVideoPayloadTypes(codecs); } @@ -92,10 +142,22 @@ void VideoCodecsModel::load () { if (find_if(codecs.begin(), codecs.end(), [](const shared_ptr &codec) { return codec->getMimeType() == "H264"; }) == codecs.end()) - addDownloadableCodec("H264", cPluginUrlH264, cH264Description); + addDownloadableCodec("H264", cH264FileName, cPluginUrlH264, cH264Description); #endif } +void VideoCodecsModel::extract(const QString &filePath) { + mFileExtractor->setFile(filePath); + mFileExtractor->extract(); +} + +void VideoCodecsModel::endInstallFile() { + mFileDownloader->remove(); + mFileDownloader->writeVersion(cH264FileName); + mFileExtractor->rename(cH264FileName); + reload(); +} + void VideoCodecsModel::reload () { beginResetModel(); load(); diff --git a/src/components/codecs/VideoCodecsModel.hpp b/src/components/codecs/VideoCodecsModel.hpp index 8b07c687a..8c7bea723 100644 --- a/src/components/codecs/VideoCodecsModel.hpp +++ b/src/components/codecs/VideoCodecsModel.hpp @@ -25,6 +25,9 @@ #include "AbstractCodecsModel.hpp" +#include "../file/FileDownloader.hpp" +#include "../file/FileExtractor.hpp" + // ============================================================================= class VideoCodecsModel : public AbstractCodecsModel { @@ -32,13 +35,20 @@ class VideoCodecsModel : public AbstractCodecsModel { public: VideoCodecsModel (QObject *parent = Q_NULLPTR); - ~VideoCodecsModel () = default; + ~VideoCodecsModel (); private: void updateCodecs (std::list> &codecs) override; + bool updateCodecVersion (const QString &filePath, const QString &newVersion); void load (); + void extract(const QString &filePath); + void installFileFailed(); + void endInstallFile(); void reload () override; + QTimer *mTimer = nullptr; + FileDownloader *mFileDownloader = nullptr; + FileExtractor *mFileExtractor = nullptr; }; #endif // VIDEO_CODECS_MODEL_H_ diff --git a/src/components/file/FileDownloader.cpp b/src/components/file/FileDownloader.cpp index 3c69acd5c..ed0e856d5 100644 --- a/src/components/file/FileDownloader.cpp +++ b/src/components/file/FileDownloader.cpp @@ -27,7 +27,7 @@ #include "FileDownloader.hpp" // ============================================================================= - +using namespace std; namespace { constexpr char cDefaultFileName[] = "download"; } @@ -105,6 +105,25 @@ bool FileDownloader::remove () { return mDestinationFile.exists() && !mDestinationFile.isOpen() && mDestinationFile.remove(); } +void FileDownloader::writeVersion(const QString &newFileName) { + QFile versionFile; + + versionFile.setFileName( + QDir::cleanPath(mDownloadFolder) + QDir::separator() + newFileName + ".txt" + ); + + Q_ASSERT(!versionFile.isOpen()); + if (versionFile.exists()) versionFile.remove(); + if (!versionFile.open(QIODevice::WriteOnly)) { + qWarning() << QStringLiteral("Unable to write version to file."); + return; + } + + string version = mUrl.toString().toStdString(); + versionFile.write(version.c_str(), qstrlen(version.c_str())); + versionFile.close(); +} + void FileDownloader::emitOutputError () { qWarning() << QStringLiteral("Could not write into `%1` (%2).") .arg(mDestinationFile.fileName()).arg(mDestinationFile.errorString()); diff --git a/src/components/file/FileDownloader.hpp b/src/components/file/FileDownloader.hpp index 86046e1b2..b64f51a75 100644 --- a/src/components/file/FileDownloader.hpp +++ b/src/components/file/FileDownloader.hpp @@ -19,7 +19,8 @@ * Created on: February 6, 2018 * Author: Danmei Chen */ - +#ifndef FILE_DOWNLOADER_H_ +#define FILE_DOWNLOADER_H_ #include #include @@ -41,6 +42,9 @@ class FileDownloader : public QObject { public: Q_INVOKABLE void download (); Q_INVOKABLE bool remove(); + Q_INVOKABLE void setUrl (const QUrl &url); + Q_INVOKABLE void setDownloadFolder (const QString &downloadFolder); + Q_INVOKABLE void writeVersion (const QString &newFileName); signals: void urlChanged (const QUrl &url); @@ -53,10 +57,8 @@ signals: private: QUrl getUrl () const; - void setUrl (const QUrl &url); QString getDownloadFolder () const; - void setDownloadFolder (const QString &downloadFolder); qint64 getReadBytes () const; void setReadBytes (qint64 readBytes); @@ -86,3 +88,4 @@ private: QPointer mNetworkReply; QNetworkAccessManager mManager; }; +#endif // FILE_DOWNLOADER_H_ \ No newline at end of file diff --git a/src/components/file/FileExtractor.cpp b/src/components/file/FileExtractor.cpp index f9e562133..b953edcdb 100644 --- a/src/components/file/FileExtractor.cpp +++ b/src/components/file/FileExtractor.cpp @@ -112,10 +112,12 @@ void FileExtractor::extract () { // 2. Open output file. // TODO: Deal with existing files. - Q_ASSERT(!mDestinationFile.isOpen()); + Q_ASSERT(!mDestinationFile.isOpen()); mDestinationFile.setFileName( QDir::cleanPath(mExtractFolder) + QDir::separator() + fileInfo.completeBaseName() ); + //TODO not sure + mDestinationFile.remove(); if (!mDestinationFile.open(QIODevice::WriteOnly)) { emitOutputError(); return; @@ -127,6 +129,18 @@ void FileExtractor::extract () { mTimer->start(); } +bool FileExtractor::remove () { + return mDestinationFile.exists() && !mDestinationFile.isOpen() && mDestinationFile.remove(); +} + +bool FileExtractor::rename (const QString &newFileName) { + const QString filePath = mExtractFolder + newFileName + "." + QFileInfo(mDestinationFile).suffix(); + //delete old file + QFile oldFile(filePath); + if(oldFile.exists()) oldFile.remove(); + return mDestinationFile.exists() && !mDestinationFile.isOpen() && mDestinationFile.rename(filePath); +} + QString FileExtractor::getFile () const { return mFile; } diff --git a/src/components/file/FileExtractor.hpp b/src/components/file/FileExtractor.hpp index 24c6f51ba..61eeed507 100644 --- a/src/components/file/FileExtractor.hpp +++ b/src/components/file/FileExtractor.hpp @@ -47,6 +47,10 @@ public: ~FileExtractor (); Q_INVOKABLE void extract (); + Q_INVOKABLE bool remove (); + Q_INVOKABLE bool rename (const QString &newFileName); + Q_INVOKABLE void setExtractFolder (const QString &extractFolder); + Q_INVOKABLE void setFile (const QString &file); signals: void fileChanged (const QString &file); @@ -59,10 +63,8 @@ signals: private: QString getFile () const; - void setFile (const QString &file); QString getExtractFolder () const; - void setExtractFolder (const QString &extractFolder); qint64 getReadBytes () const; void setReadBytes (qint64 readBytes); diff --git a/ui/modules/Linphone/Dialog/OnlineInstallerDialog.qml b/ui/modules/Linphone/Dialog/OnlineInstallerDialog.qml index 89016e5f8..be5f6e7e9 100644 --- a/ui/modules/Linphone/Dialog/OnlineInstallerDialog.qml +++ b/ui/modules/Linphone/Dialog/OnlineInstallerDialog.qml @@ -17,6 +17,7 @@ DialogPlus { property alias installFolder: fileDownloader.downloadFolder property bool extract: false property string fileName + property string newFileName property bool _installing: false property int _exitStatus: -1 // Not downloaded for the moment. @@ -29,8 +30,11 @@ DialogPlus { } function _endInstall (exitStatus) { - if (dialog.extract) + if (dialog.extract) { fileDownloader.remove() + fileDownloader.writeVersion(newFileName) + fileExtractor.rename(newFileName) + } dialog._exitStatus = exitStatus dialog._installing = false } @@ -108,13 +112,16 @@ DialogPlus { } Text { + id: text + property var target: fileDownloader + anchors.right: parent.right color: OnlineInstallerDialogStyle.column.text.color font.pointSize: OnlineInstallerDialogStyle.column.text.pointSize text: { - var fileSize = Utils.formatSize(fileDownloader.totalBytes) - return Utils.formatSize(fileDownloader.readBytes) + '/' + fileSize + var fileSize = Utils.formatSize(target.totalBytes) + return Utils.formatSize(target.readBytes) + '/' + fileSize } } @@ -126,6 +133,7 @@ DialogPlus { fileExtractor.file = filePath if (dialog.extract) { progressBar.target = fileExtractor + text.target = fileExtractor fileExtractor.extract() } else { dialog._endInstall(1) diff --git a/ui/scripts/LinphoneUtils/linphone-utils.js b/ui/scripts/LinphoneUtils/linphone-utils.js index c64a3b106..beefa4cae 100644 --- a/ui/scripts/LinphoneUtils/linphone-utils.js +++ b/ui/scripts/LinphoneUtils/linphone-utils.js @@ -105,6 +105,7 @@ function openCodecOnlineInstallerDialog (window, codecInfo, cb) { downloadUrl: codecInfo.downloadUrl, extract: true, fileName: codecInfo.mime, + newFileName: codecInfo.fileName, installFolder: VideoCodecsModel.codecsFolder }, function (status) { if (status) {