1 /****************************************************************************** 2 Copyright (C) 2014 by Ruwen Hahn <palana@stunned.de> 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 ******************************************************************************/ 17 18 #pragma once 19 20 #include <QFileInfo> 21 #include <QMutex> 22 #include <QPointer> 23 #include <QThread> 24 #include <QStyledItemDelegate> 25 #include <memory> 26 #include "ui_OBSRemux.h" 27 28 #include <media-io/media-remux.h> 29 #include <util/threading.h> 30 31 class RemuxQueueModel; 32 class RemuxWorker; 33 34 enum RemuxEntryState { 35 Empty, 36 Ready, 37 Pending, 38 InProgress, 39 Complete, 40 InvalidPath, 41 Error 42 }; 43 Q_DECLARE_METATYPE(RemuxEntryState); 44 45 class OBSRemux : public QDialog { 46 Q_OBJECT 47 48 QPointer<RemuxQueueModel> queueModel; 49 QThread remuxer; 50 QPointer<RemuxWorker> worker; 51 52 std::unique_ptr<Ui::OBSRemux> ui; 53 54 const char *recPath; 55 56 virtual void closeEvent(QCloseEvent *event) override; 57 virtual void reject() override; 58 59 bool autoRemux; 60 QString autoRemuxFile; 61 62 public: 63 explicit OBSRemux(const char *recPath, QWidget *parent = nullptr, 64 bool autoRemux = false); 65 virtual ~OBSRemux() override; 66 67 using job_t = std::shared_ptr<struct media_remux_job>; 68 69 void AutoRemux(QString inFile, QString outFile); 70 71 protected: 72 virtual void dropEvent(QDropEvent *ev) override; 73 virtual void dragEnterEvent(QDragEnterEvent *ev) override; 74 75 void remuxNextEntry(); 76 77 private slots: 78 void rowCountChanged(const QModelIndex &parent, int first, int last); 79 80 public slots: 81 void updateProgress(float percent); 82 void remuxFinished(bool success); 83 void beginRemux(); 84 bool stopRemux(); 85 void clearFinished(); 86 void clearAll(); 87 88 signals: 89 void remux(const QString &source, const QString &target); 90 }; 91 92 class RemuxQueueModel : public QAbstractTableModel { 93 Q_OBJECT 94 95 friend class OBSRemux; 96 97 public: RemuxQueueModel(QObject * parent=0)98 RemuxQueueModel(QObject *parent = 0) 99 : QAbstractTableModel(parent), isProcessing(false) 100 { 101 } 102 103 int rowCount(const QModelIndex &parent = QModelIndex()) const; 104 int columnCount(const QModelIndex &parent = QModelIndex()) const; 105 QVariant data(const QModelIndex &index, int role) const; 106 QVariant headerData(int section, Qt::Orientation orientation, 107 int role = Qt::DisplayRole) const; 108 Qt::ItemFlags flags(const QModelIndex &index) const; 109 bool setData(const QModelIndex &index, const QVariant &value, int role); 110 111 QFileInfoList checkForOverwrites() const; 112 bool checkForErrors() const; 113 void beginProcessing(); 114 void endProcessing(); 115 bool beginNextEntry(QString &inputPath, QString &outputPath); 116 void finishEntry(bool success); 117 bool canClearFinished() const; 118 void clearFinished(); 119 void clearAll(); 120 121 bool autoRemux = false; 122 123 private: 124 struct RemuxQueueEntry { 125 RemuxEntryState state; 126 127 QString sourcePath; 128 QString targetPath; 129 }; 130 131 QList<RemuxQueueEntry> queue; 132 bool isProcessing; 133 134 static QVariant getIcon(RemuxEntryState state); 135 136 void checkInputPath(int row); 137 }; 138 139 class RemuxWorker : public QObject { 140 Q_OBJECT 141 142 QMutex updateMutex; 143 144 bool isWorking; 145 146 float lastProgress; 147 void UpdateProgress(float percent); 148 RemuxWorker()149 explicit RemuxWorker() : isWorking(false) {} ~RemuxWorker()150 virtual ~RemuxWorker(){}; 151 152 private slots: 153 void remux(const QString &source, const QString &target); 154 155 signals: 156 void updateProgress(float percent); 157 void remuxFinished(bool success); 158 159 friend class OBSRemux; 160 }; 161 162 class RemuxEntryPathItemDelegate : public QStyledItemDelegate { 163 Q_OBJECT 164 165 public: 166 RemuxEntryPathItemDelegate(bool isOutput, const QString &defaultPath); 167 168 virtual QWidget *createEditor(QWidget *parent, 169 const QStyleOptionViewItem & /* option */, 170 const QModelIndex &index) const override; 171 172 virtual void setEditorData(QWidget *editor, 173 const QModelIndex &index) const override; 174 virtual void setModelData(QWidget *editor, QAbstractItemModel *model, 175 const QModelIndex &index) const override; 176 virtual void paint(QPainter *painter, 177 const QStyleOptionViewItem &option, 178 const QModelIndex &index) const override; 179 180 private: 181 bool isOutput; 182 QString defaultPath; 183 const char *PATH_LIST_PROP = "pathList"; 184 185 void handleBrowse(QWidget *container); 186 void handleClear(QWidget *container); 187 188 private slots: 189 void updateText(); 190 }; 191