3dc1b7f3d5
The remuxer thread was only started if there was an actual remux job, which resulted in the remuxer thread not being able to call the worker's destructor (because it wasn't running)
228 lines
5.2 KiB
C++
228 lines
5.2 KiB
C++
/******************************************************************************
|
|
Copyright (C) 2014 by Ruwen Hahn <palana@stunned.de>
|
|
|
|
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 2 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 "window-remux.hpp"
|
|
|
|
#include "obs-app.hpp"
|
|
|
|
#include <QCloseEvent>
|
|
#include <QFileDialog>
|
|
#include <QFileInfo>
|
|
#include <QMessageBox>
|
|
|
|
#include "qt-wrappers.hpp"
|
|
|
|
#include <memory>
|
|
#include <cmath>
|
|
|
|
using namespace std;
|
|
|
|
OBSRemux::OBSRemux(const char *path, QWidget *parent)
|
|
: QDialog (parent),
|
|
worker (new RemuxWorker),
|
|
ui (new Ui::OBSRemux),
|
|
recPath (path)
|
|
{
|
|
ui->setupUi(this);
|
|
|
|
ui->progressBar->setVisible(false);
|
|
ui->remux->setEnabled(false);
|
|
ui->targetFile->setEnabled(false);
|
|
ui->browseTarget->setEnabled(false);
|
|
|
|
ui->progressBar->setMinimum(0);
|
|
ui->progressBar->setMaximum(1000);
|
|
ui->progressBar->setValue(0);
|
|
|
|
connect(ui->browseSource, &QPushButton::clicked,
|
|
[&]() { BrowseInput(); });
|
|
connect(ui->browseTarget, &QPushButton::clicked,
|
|
[&]() { BrowseOutput(); });
|
|
connect(ui->remux, &QPushButton::clicked, [&]() { Remux(); });
|
|
|
|
connect(ui->sourceFile, &QLineEdit::textChanged,
|
|
this, &OBSRemux::inputChanged);
|
|
|
|
worker->moveToThread(&remuxer);
|
|
remuxer.start();
|
|
|
|
//gcc-4.8 can't use QPointer<RemuxWorker> below
|
|
RemuxWorker *worker_ = worker;
|
|
connect(worker_, &RemuxWorker::updateProgress,
|
|
this, &OBSRemux::updateProgress);
|
|
connect(&remuxer, &QThread::finished, worker_, &QObject::deleteLater);
|
|
connect(worker_, &RemuxWorker::remuxFinished,
|
|
this, &OBSRemux::remuxFinished);
|
|
connect(this, &OBSRemux::remux, worker_, &RemuxWorker::remux);
|
|
}
|
|
|
|
bool OBSRemux::Stop()
|
|
{
|
|
if (!worker->job)
|
|
return true;
|
|
|
|
if (QMessageBox::critical(nullptr,
|
|
QTStr("Remux.ExitUnfinishedTitle"),
|
|
QTStr("Remux.ExitUnfinished"),
|
|
QMessageBox::Yes | QMessageBox::No,
|
|
QMessageBox::No) ==
|
|
QMessageBox::Yes) {
|
|
os_event_signal(worker->stop);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
OBSRemux::~OBSRemux()
|
|
{
|
|
Stop();
|
|
remuxer.quit();
|
|
remuxer.wait();
|
|
}
|
|
|
|
void OBSRemux::BrowseInput()
|
|
{
|
|
QString path = ui->sourceFile->text();
|
|
if (path.isEmpty())
|
|
path = recPath;
|
|
|
|
path = QFileDialog::getOpenFileName(this,
|
|
QTStr("Remux.SelectRecording"), path,
|
|
QTStr("Remux.RecordingPattern"));
|
|
|
|
inputChanged(path);
|
|
}
|
|
|
|
void OBSRemux::inputChanged(const QString &path)
|
|
{
|
|
if (!QFileInfo::exists(path)) {
|
|
ui->remux->setEnabled(false);
|
|
return;
|
|
}
|
|
|
|
ui->sourceFile->setText(path);
|
|
ui->remux->setEnabled(true);
|
|
|
|
QFileInfo fi(path);
|
|
QString mp4 = fi.path() + "/" + fi.baseName() + ".mp4";
|
|
ui->targetFile->setText(mp4);
|
|
|
|
ui->targetFile->setEnabled(true);
|
|
ui->browseTarget->setEnabled(true);
|
|
}
|
|
|
|
void OBSRemux::BrowseOutput()
|
|
{
|
|
QString path(ui->targetFile->text());
|
|
path = QFileDialog::getSaveFileName(this, QTStr("Remux.SelectTarget"),
|
|
path, "(*.mp4)");
|
|
|
|
if (path.isEmpty())
|
|
return;
|
|
|
|
ui->targetFile->setText(path);
|
|
}
|
|
|
|
void OBSRemux::Remux()
|
|
{
|
|
if (QFileInfo::exists(ui->targetFile->text()))
|
|
if (QMessageBox::question(this, QTStr("Remux.FileExistsTitle"),
|
|
QTStr("Remux.FileExists"),
|
|
QMessageBox::Yes | QMessageBox::No) !=
|
|
QMessageBox::Yes)
|
|
return;
|
|
|
|
media_remux_job_t mr_job = nullptr;
|
|
if (!media_remux_job_create(&mr_job, QT_TO_UTF8(ui->sourceFile->text()),
|
|
QT_TO_UTF8(ui->targetFile->text())))
|
|
return;
|
|
|
|
worker->job = job_t(mr_job, media_remux_job_destroy);
|
|
worker->lastProgress = 0.f;
|
|
|
|
ui->progressBar->setVisible(true);
|
|
ui->remux->setEnabled(false);
|
|
|
|
emit remux();
|
|
}
|
|
|
|
void OBSRemux::closeEvent(QCloseEvent *event)
|
|
{
|
|
if (!Stop())
|
|
event->ignore();
|
|
else
|
|
QDialog::closeEvent(event);
|
|
}
|
|
|
|
void OBSRemux::reject()
|
|
{
|
|
if (!Stop())
|
|
return;
|
|
|
|
QDialog::reject();
|
|
}
|
|
|
|
void OBSRemux::updateProgress(float percent)
|
|
{
|
|
ui->progressBar->setValue(percent * 10);
|
|
}
|
|
|
|
void OBSRemux::remuxFinished(bool success)
|
|
{
|
|
QMessageBox::information(this, QTStr("Remux.FinishedTitle"),
|
|
success ?
|
|
QTStr("Remux.Finished") : QTStr("Remux.FinishedError"));
|
|
|
|
worker->job.reset();
|
|
ui->progressBar->setVisible(false);
|
|
ui->remux->setEnabled(true);
|
|
}
|
|
|
|
RemuxWorker::RemuxWorker()
|
|
{
|
|
os_event_init(&stop, OS_EVENT_TYPE_MANUAL);
|
|
}
|
|
|
|
RemuxWorker::~RemuxWorker()
|
|
{
|
|
os_event_destroy(stop);
|
|
}
|
|
|
|
void RemuxWorker::UpdateProgress(float percent)
|
|
{
|
|
if (abs(lastProgress - percent) < 0.1f)
|
|
return;
|
|
|
|
emit updateProgress(percent);
|
|
lastProgress = percent;
|
|
}
|
|
|
|
void RemuxWorker::remux()
|
|
{
|
|
auto callback = [](void *data, float percent)
|
|
{
|
|
auto rw = static_cast<RemuxWorker*>(data);
|
|
rw->UpdateProgress(percent);
|
|
return !!os_event_try(rw->stop);
|
|
};
|
|
|
|
bool success = media_remux_job_process(job.get(), callback, this);
|
|
|
|
emit remuxFinished(os_event_try(stop) && success);
|
|
}
|