work towards exports working on threaded gl
This commit is contained in:
+59
-61
@@ -57,7 +57,7 @@ enum ExportFormats {
|
||||
ExportDialog::ExportDialog(QWidget *parent) :
|
||||
QDialog(parent)
|
||||
{
|
||||
setWindowTitle(tr("Export \"%1\"").arg(sequence->name));
|
||||
setWindowTitle(tr("Export \"%1\"").arg(sequence->name));
|
||||
setup_ui();
|
||||
|
||||
rangeCombobox->setCurrentIndex(0);
|
||||
@@ -320,12 +320,12 @@ void ExportDialog::format_changed(int index)
|
||||
|
||||
void ExportDialog::render_thread_finished() {
|
||||
if (progressBar->value() < 100 && !cancelled) {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Export Failed"),
|
||||
tr("Export failed - %1").arg(export_error),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Export Failed"),
|
||||
tr("Export failed - %1").arg(export_error),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
}
|
||||
prep_ui_for_render(false);
|
||||
panel_sequence_viewer->viewer_widget->makeCurrent();
|
||||
@@ -342,12 +342,12 @@ void ExportDialog::prep_ui_for_render(bool r) {
|
||||
|
||||
void ExportDialog::export_action() {
|
||||
if (widthSpinbox->value()%2 == 1 || heightSpinbox->value()%2 == 1) {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Invalid dimensions"),
|
||||
tr("Export width and height must both be even numbers/divisible by 2."),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Invalid dimensions"),
|
||||
tr("Export width and height must both be even numbers/divisible by 2."),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -399,12 +399,12 @@ void ExportDialog::export_action() {
|
||||
break;
|
||||
default:
|
||||
qCritical() << "Invalid codec selection for an image sequence";
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Invalid codec"),
|
||||
tr("Couldn't determine output parameters for the selected codec. This is a bug, please contact the developers."),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Invalid codec"),
|
||||
tr("Couldn't determine output parameters for the selected codec. This is a bug, please contact the developers."),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -469,20 +469,20 @@ void ExportDialog::export_action() {
|
||||
break;
|
||||
default:
|
||||
qCritical() << "Invalid format - this is a bug, please inform the developers";
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Invalid format"),
|
||||
tr("Couldn't determine output format. This is a bug, please contact the developers."),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Invalid format"),
|
||||
tr("Couldn't determine output format. This is a bug, please contact the developers."),
|
||||
QMessageBox::Ok
|
||||
);
|
||||
return;
|
||||
}
|
||||
QString filename = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
tr("Export Media"),
|
||||
"",
|
||||
format_strings[formatCombobox->currentIndex()] + " (*." + ext + ")"
|
||||
);
|
||||
QString filename = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
tr("Export Media"),
|
||||
"",
|
||||
format_strings[formatCombobox->currentIndex()] + " (*." + ext + ")"
|
||||
);
|
||||
if (!filename.isEmpty()) {
|
||||
if (!filename.endsWith("." + ext, Qt::CaseInsensitive)) {
|
||||
filename += "." + ext;
|
||||
@@ -506,11 +506,9 @@ void ExportDialog::export_action() {
|
||||
|
||||
closeActiveClips(sequence);
|
||||
|
||||
mainWindow->autorecover_interval();
|
||||
mainWindow->set_rendering_state(true);
|
||||
|
||||
rendering = true;
|
||||
panel_sequence_viewer->viewer_widget->context()->doneCurrent();
|
||||
panel_sequence_viewer->viewer_widget->context()->moveToThread(et);
|
||||
mainWindow->autorecover_interval();
|
||||
|
||||
prep_ui_for_render(true);
|
||||
|
||||
@@ -565,11 +563,11 @@ void ExportDialog::vcodec_changed(int index) {
|
||||
compressionTypeCombobox->clear();
|
||||
if ((format_vcodecs.size() > 0 && format_vcodecs.at(index) == AV_CODEC_ID_H264)) {
|
||||
compressionTypeCombobox->setEnabled(true);
|
||||
compressionTypeCombobox->addItem(tr("Quality-based (Constant Rate Factor)"), COMPRESSION_TYPE_CFR);
|
||||
compressionTypeCombobox->addItem(tr("Quality-based (Constant Rate Factor)"), COMPRESSION_TYPE_CFR);
|
||||
// compressionTypeCombobox->addItem("File size-based (Two-Pass)", COMPRESSION_TYPE_TARGETSIZE);
|
||||
// compressionTypeCombobox->addItem("Average bitrate (Two-Pass)", COMPRESSION_TYPE_TARGETBR);
|
||||
} else {
|
||||
compressionTypeCombobox->addItem(tr("Constant Bitrate"), COMPRESSION_TYPE_CBR);
|
||||
compressionTypeCombobox->addItem(tr("Constant Bitrate"), COMPRESSION_TYPE_CBR);
|
||||
compressionTypeCombobox->setCurrentIndex(0);
|
||||
compressionTypeCombobox->setEnabled(false);
|
||||
}
|
||||
@@ -582,17 +580,17 @@ void ExportDialog::comp_type_changed(int) {
|
||||
switch (compressionTypeCombobox->currentData().toInt()) {
|
||||
case COMPRESSION_TYPE_CBR:
|
||||
case COMPRESSION_TYPE_TARGETBR:
|
||||
videoBitrateLabel->setText(tr("Bitrate (Mbps):"));
|
||||
videoBitrateLabel->setText(tr("Bitrate (Mbps):"));
|
||||
videobitrateSpinbox->setValue(qMax(0.5, (double) qRound((0.01528 * sequence->height) - 4.5)));
|
||||
break;
|
||||
case COMPRESSION_TYPE_CFR:
|
||||
videoBitrateLabel->setText(tr("Quality (CRF):"));
|
||||
videoBitrateLabel->setText(tr("Quality (CRF):"));
|
||||
videobitrateSpinbox->setValue(36);
|
||||
videobitrateSpinbox->setMaximum(51);
|
||||
videobitrateSpinbox->setToolTip(tr("Quality Factor:\n\n0 = lossless\n17-18 = visually lossless (compressed, but unnoticeable)\n23 = high quality\n51 = lowest quality possible"));
|
||||
videobitrateSpinbox->setToolTip(tr("Quality Factor:\n\n0 = lossless\n17-18 = visually lossless (compressed, but unnoticeable)\n23 = high quality\n51 = lowest quality possible"));
|
||||
break;
|
||||
case COMPRESSION_TYPE_TARGETSIZE:
|
||||
videoBitrateLabel->setText(tr("Target File Size (MB):"));
|
||||
videoBitrateLabel->setText(tr("Target File Size (MB):"));
|
||||
videobitrateSpinbox->setValue(100);
|
||||
break;
|
||||
}
|
||||
@@ -601,57 +599,57 @@ void ExportDialog::comp_type_changed(int) {
|
||||
void ExportDialog::setup_ui() {
|
||||
QVBoxLayout* verticalLayout = new QVBoxLayout(this);
|
||||
|
||||
QHBoxLayout* format_layout = new QHBoxLayout();
|
||||
QHBoxLayout* format_layout = new QHBoxLayout();
|
||||
|
||||
format_layout->addWidget(new QLabel(tr("Format:")));
|
||||
format_layout->addWidget(new QLabel(tr("Format:")));
|
||||
|
||||
formatCombobox = new QComboBox(this);
|
||||
|
||||
format_layout->addWidget(formatCombobox);
|
||||
format_layout->addWidget(formatCombobox);
|
||||
|
||||
verticalLayout->addLayout(format_layout);
|
||||
verticalLayout->addLayout(format_layout);
|
||||
|
||||
QHBoxLayout* range_layout = new QHBoxLayout();
|
||||
QHBoxLayout* range_layout = new QHBoxLayout();
|
||||
|
||||
range_layout->addWidget(new QLabel(tr("Range:")));
|
||||
range_layout->addWidget(new QLabel(tr("Range:")));
|
||||
|
||||
rangeCombobox = new QComboBox(this);
|
||||
rangeCombobox->addItem(tr("Entire Sequence"));
|
||||
rangeCombobox->addItem(tr("In to Out"));
|
||||
rangeCombobox->addItem(tr("Entire Sequence"));
|
||||
rangeCombobox->addItem(tr("In to Out"));
|
||||
|
||||
range_layout->addWidget(rangeCombobox);
|
||||
range_layout->addWidget(rangeCombobox);
|
||||
|
||||
verticalLayout->addLayout(range_layout);
|
||||
verticalLayout->addLayout(range_layout);
|
||||
|
||||
videoGroupbox = new QGroupBox(this);
|
||||
videoGroupbox->setTitle(tr("Video"));
|
||||
videoGroupbox->setTitle(tr("Video"));
|
||||
videoGroupbox->setFlat(false);
|
||||
videoGroupbox->setCheckable(true);
|
||||
|
||||
QGridLayout* videoGridLayout = new QGridLayout(videoGroupbox);
|
||||
|
||||
videoGridLayout->addWidget(new QLabel(tr("Codec:")), 0, 0, 1, 1);
|
||||
videoGridLayout->addWidget(new QLabel(tr("Codec:")), 0, 0, 1, 1);
|
||||
vcodecCombobox = new QComboBox(videoGroupbox);
|
||||
videoGridLayout->addWidget(vcodecCombobox, 0, 1, 1, 1);
|
||||
|
||||
videoGridLayout->addWidget(new QLabel(tr("Width:")), 1, 0, 1, 1);
|
||||
videoGridLayout->addWidget(new QLabel(tr("Width:")), 1, 0, 1, 1);
|
||||
widthSpinbox = new QSpinBox(videoGroupbox);
|
||||
widthSpinbox->setMaximum(16777216);
|
||||
videoGridLayout->addWidget(widthSpinbox, 1, 1, 1, 1);
|
||||
|
||||
videoGridLayout->addWidget(new QLabel(tr("Height:")), 2, 0, 1, 1);
|
||||
videoGridLayout->addWidget(new QLabel(tr("Height:")), 2, 0, 1, 1);
|
||||
heightSpinbox = new QSpinBox(videoGroupbox);
|
||||
heightSpinbox->setMaximum(16777216);
|
||||
videoGridLayout->addWidget(heightSpinbox, 2, 1, 1, 1);
|
||||
|
||||
videoGridLayout->addWidget(new QLabel(tr("Frame Rate:")), 3, 0, 1, 1);
|
||||
videoGridLayout->addWidget(new QLabel(tr("Frame Rate:")), 3, 0, 1, 1);
|
||||
framerateSpinbox = new QDoubleSpinBox(videoGroupbox);
|
||||
framerateSpinbox->setMaximum(60);
|
||||
framerateSpinbox->setValue(0);
|
||||
videoGridLayout->addWidget(framerateSpinbox, 3, 1, 1, 1);
|
||||
|
||||
videoGridLayout->addWidget(new QLabel(tr("Compression Type:")), 4, 0, 1, 1);
|
||||
compressionTypeCombobox = new QComboBox(videoGroupbox);
|
||||
videoGridLayout->addWidget(new QLabel(tr("Compression Type:")), 4, 0, 1, 1);
|
||||
compressionTypeCombobox = new QComboBox(videoGroupbox);
|
||||
videoGridLayout->addWidget(compressionTypeCombobox, 4, 1, 1, 1);
|
||||
|
||||
videoBitrateLabel = new QLabel(videoGroupbox);
|
||||
@@ -669,17 +667,17 @@ void ExportDialog::setup_ui() {
|
||||
|
||||
QGridLayout* audioGridLayout = new QGridLayout(audioGroupbox);
|
||||
|
||||
audioGridLayout->addWidget(new QLabel(tr("Codec:")), 0, 0, 1, 1);
|
||||
audioGridLayout->addWidget(new QLabel(tr("Codec:")), 0, 0, 1, 1);
|
||||
acodecCombobox = new QComboBox(audioGroupbox);
|
||||
audioGridLayout->addWidget(acodecCombobox, 0, 1, 1, 1);
|
||||
|
||||
audioGridLayout->addWidget(new QLabel(tr("Sampling Rate:")), 1, 0, 1, 1);
|
||||
audioGridLayout->addWidget(new QLabel(tr("Sampling Rate:")), 1, 0, 1, 1);
|
||||
samplingRateSpinbox = new QSpinBox(audioGroupbox);
|
||||
samplingRateSpinbox->setMaximum(96000);
|
||||
samplingRateSpinbox->setValue(0);
|
||||
audioGridLayout->addWidget(samplingRateSpinbox, 1, 1, 1, 1);
|
||||
|
||||
audioGridLayout->addWidget(new QLabel(tr("Bitrate (Kbps/CBR):")), 3, 0, 1, 1);
|
||||
audioGridLayout->addWidget(new QLabel(tr("Bitrate (Kbps/CBR):")), 3, 0, 1, 1);
|
||||
audiobitrateSpinbox = new QSpinBox(audioGroupbox);
|
||||
audiobitrateSpinbox->setMaximum(320);
|
||||
audiobitrateSpinbox->setValue(256);
|
||||
|
||||
+4
-19
@@ -9,6 +9,7 @@
|
||||
#include "playback/playback.h"
|
||||
#include "playback/audio.h"
|
||||
#include "dialogs/exportdialog.h"
|
||||
#include "mainwindow.h"
|
||||
#include "debug.h"
|
||||
|
||||
extern "C" {
|
||||
@@ -111,7 +112,7 @@ bool ExportThread::setupVideo() {
|
||||
vcodec_ctx->sample_aspect_ratio = {1, 1};
|
||||
vcodec_ctx->pix_fmt = vcodec->pix_fmts[0]; // maybe be breakable code
|
||||
vcodec_ctx->framerate = av_d2q(video_frame_rate, INT_MAX);
|
||||
if (video_compression_type == COMPRESSION_TYPE_CBR) vcodec_ctx->bit_rate = video_bitrate * 1000000;
|
||||
if (video_compression_type == COMPRESSION_TYPE_CBR) vcodec_ctx->bit_rate = qRound(video_bitrate * 1000000);
|
||||
vcodec_ctx->time_base = av_inv_q(vcodec_ctx->framerate);
|
||||
video_stream->time_base = vcodec_ctx->time_base;
|
||||
|
||||
@@ -312,12 +313,7 @@ bool ExportThread::setupContainer() {
|
||||
|
||||
void ExportThread::run() {
|
||||
panel_sequence_viewer->pause();
|
||||
|
||||
if (!panel_sequence_viewer->viewer_widget->context()->makeCurrent(&surface)) {
|
||||
qCritical() << "Make current failed";
|
||||
ed->export_error = tr("could not make OpenGL context current");
|
||||
return;
|
||||
}
|
||||
panel_sequence_viewer->seek(start_frame);
|
||||
|
||||
// copy filename
|
||||
QByteArray ba = filename.toUtf8();
|
||||
@@ -339,14 +335,9 @@ void ExportThread::run() {
|
||||
}
|
||||
}
|
||||
|
||||
panel_sequence_viewer->seek(start_frame);
|
||||
panel_sequence_viewer->reset_all_audio();
|
||||
|
||||
QOpenGLFramebufferObject fbo(sequence->width, sequence->height, QOpenGLFramebufferObject::CombinedDepthStencil, GL_TEXTURE_RECTANGLE);
|
||||
fbo.bind();
|
||||
|
||||
panel_sequence_viewer->viewer_widget->default_fbo = &fbo;
|
||||
|
||||
long file_audio_samples = 0;
|
||||
qint64 start_time, frame_time, avg_time, eta, total_time = 0;
|
||||
long remaining_frames, frame_count = 1;
|
||||
@@ -415,8 +406,7 @@ void ExportThread::run() {
|
||||
if (audio_enabled) apkt_alloc = true;
|
||||
}
|
||||
|
||||
panel_sequence_viewer->viewer_widget->default_fbo = nullptr;
|
||||
rendering = false;
|
||||
mainWindow->set_rendering_state(false);
|
||||
|
||||
fbo.release();
|
||||
|
||||
@@ -478,9 +468,4 @@ void ExportThread::run() {
|
||||
}
|
||||
|
||||
delete [] c_filename;
|
||||
|
||||
panel_sequence_viewer->viewer_widget->context()->doneCurrent();
|
||||
panel_sequence_viewer->viewer_widget->context()->moveToThread(qApp->thread());
|
||||
|
||||
rendering = false;
|
||||
}
|
||||
|
||||
+10
-1
@@ -351,6 +351,15 @@ void MainWindow::load_css_from_file(const QString &fn) {
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::set_rendering_state(bool rendering) {
|
||||
audio_rendering = rendering;
|
||||
if (rendering) {
|
||||
autorecovery_timer.stop();
|
||||
} else {
|
||||
autorecovery_timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::show_about() {
|
||||
AboutDialog a(this);
|
||||
a.exec();
|
||||
@@ -502,7 +511,7 @@ void MainWindow::new_project() {
|
||||
}
|
||||
|
||||
void MainWindow::autorecover_interval() {
|
||||
if (!rendering && isWindowModified()) {
|
||||
if (isWindowModified()) {
|
||||
panel_project->save_project(true);
|
||||
qInfo() << "Auto-recovery project saved";
|
||||
}
|
||||
|
||||
+3
-1
@@ -23,7 +23,9 @@ public:
|
||||
void load_shortcuts(const QString &fn, bool first = false);
|
||||
void save_shortcuts(const QString &fn);
|
||||
|
||||
void load_css_from_file(const QString& fn);
|
||||
void load_css_from_file(const QString& fn);
|
||||
|
||||
void set_rendering_state(bool rendering);
|
||||
|
||||
public slots:
|
||||
void undo();
|
||||
|
||||
+2
-1
@@ -29,6 +29,7 @@ bool audio_scrub = false;
|
||||
QMutex audio_write_lock;
|
||||
QAudioInput* audio_input = nullptr;
|
||||
QFile output_recording;
|
||||
bool audio_rendering = false;
|
||||
bool recording = false;
|
||||
|
||||
qint8 audio_ibuffer[audio_ibuffer_size];
|
||||
@@ -110,7 +111,7 @@ void clear_audio_ibuffer() {
|
||||
}
|
||||
|
||||
int current_audio_freq() {
|
||||
return rendering ? sequence->audio_frequency : audio_output->format().sampleRate();
|
||||
return audio_rendering ? sequence->audio_frequency : audio_output->format().sampleRate();
|
||||
}
|
||||
|
||||
int get_buffer_offset_from_frame(double framerate, long frame) {
|
||||
|
||||
+2
-1
@@ -41,6 +41,8 @@ extern int audio_ibuffer_read;
|
||||
extern long audio_ibuffer_frame;
|
||||
extern double audio_ibuffer_timecode;
|
||||
extern bool audio_scrub;
|
||||
extern bool recording;
|
||||
extern bool audio_rendering;
|
||||
void clear_audio_ibuffer();
|
||||
|
||||
int current_audio_freq();
|
||||
@@ -54,6 +56,5 @@ int get_buffer_offset_from_frame(double framerate, long frame);
|
||||
bool start_recording();
|
||||
void stop_recording();
|
||||
QString get_recorded_audio_filename();
|
||||
extern bool recording;
|
||||
|
||||
#endif // AUDIO_H
|
||||
|
||||
@@ -9,8 +9,6 @@ struct ClipCache;
|
||||
struct Sequence;
|
||||
struct AVFrame;
|
||||
|
||||
extern bool rendering;
|
||||
|
||||
long refactor_frame_number(long framenumber, double source_frame_rate, double target_frame_rate);
|
||||
bool clip_uses_cacher(Clip* clip);
|
||||
void open_clip(Clip* clip, bool multithreaded);
|
||||
|
||||
@@ -118,7 +118,8 @@ GLuint compose_sequence(Viewer* viewer,
|
||||
bool video,
|
||||
bool render_audio,
|
||||
Effect** gizmos,
|
||||
bool& texture_failed) {
|
||||
bool& texture_failed,
|
||||
bool rendering) {
|
||||
GLint current_fbo = 0;
|
||||
if (video) {
|
||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo);
|
||||
@@ -284,7 +285,7 @@ GLuint compose_sequence(Viewer* viewer,
|
||||
// for nested sequences
|
||||
if (c->media->get_type()== MEDIA_TYPE_SEQUENCE) {
|
||||
nests.append(c);
|
||||
textureID = compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed);
|
||||
textureID = compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed, rendering);
|
||||
nests.removeLast();
|
||||
fbo_switcher = true;
|
||||
}
|
||||
@@ -455,7 +456,7 @@ GLuint compose_sequence(Viewer* viewer,
|
||||
if (render_audio || (config.enable_audio_scrubbing && audio_scrub)) {
|
||||
if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) {
|
||||
nests.append(c);
|
||||
compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed);
|
||||
compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed, rendering);
|
||||
nests.removeLast();
|
||||
} else {
|
||||
if (c->lock.tryLock()) {
|
||||
|
||||
@@ -15,6 +15,8 @@ GLuint compose_sequence(Viewer* viewer,
|
||||
QVector<Clip*>& nests,
|
||||
bool video,
|
||||
bool render_audio,
|
||||
Effect **gizmos, bool &texture_failed);
|
||||
Effect **gizmos,
|
||||
bool &texture_failed,
|
||||
bool rendering);
|
||||
|
||||
#endif // RENDERFUNCTIONS_H
|
||||
|
||||
+22
-10
@@ -109,20 +109,33 @@ void RenderThread::paint() {
|
||||
Effect* gizmos; // does nothing yet
|
||||
QVector<Clip*> nests;
|
||||
|
||||
compose_sequence(nullptr, ctx, seq, nests, true, false, &gizmos, texture_failed);
|
||||
compose_sequence(nullptr, ctx, seq, nests, true, false, &gizmos, texture_failed, false);
|
||||
|
||||
if (!save_fn.isEmpty()) {
|
||||
if (texture_failed) {
|
||||
// texture failed, try again
|
||||
queued = true;
|
||||
} else {
|
||||
ctx->functions()->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer);
|
||||
QImage img(tex_width, tex_height, QImage::Format_RGBA8888);
|
||||
glReadPixels(0, 0, tex_width, tex_height, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
img.mirrored(false, true).save(save_fn);
|
||||
ctx->functions()->glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
save_fn = "";
|
||||
}
|
||||
}
|
||||
|
||||
glDisable(GL_DEPTH);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void RenderThread::start_render(QOpenGLContext *share, Sequence *s, int idivider) {
|
||||
if (s != seq && seq != nullptr) {
|
||||
closeActiveClips(seq);
|
||||
}
|
||||
|
||||
void RenderThread::start_render(QOpenGLContext *share, Sequence *s, const QString& save, int idivider) {
|
||||
seq = s;
|
||||
|
||||
// stall any dependent actions
|
||||
texture_failed = true;
|
||||
|
||||
if (share != nullptr && (ctx == nullptr || ctx->shareContext() != share_ctx)) {
|
||||
share_ctx = share;
|
||||
delete_ctx();
|
||||
@@ -133,10 +146,9 @@ void RenderThread::start_render(QOpenGLContext *share, Sequence *s, int idivider
|
||||
ctx->moveToThread(this);
|
||||
}
|
||||
|
||||
if (seq != nullptr) {
|
||||
queued = true;
|
||||
waitCond.wakeAll();
|
||||
}
|
||||
save_fn = save;
|
||||
queued = true;
|
||||
waitCond.wakeAll();
|
||||
}
|
||||
|
||||
bool RenderThread::did_texture_fail() {
|
||||
|
||||
+2
-1
@@ -20,7 +20,7 @@ public:
|
||||
GLuint frameBuffer;
|
||||
GLuint texColorBuffer;
|
||||
void paint();
|
||||
void start_render(QOpenGLContext* share, Sequence* s, int idivider = 0);
|
||||
void start_render(QOpenGLContext* share, Sequence* s, const QString &save = nullptr, int idivider = 0);
|
||||
bool did_texture_fail();
|
||||
void cancel();
|
||||
signals:
|
||||
@@ -42,6 +42,7 @@ private:
|
||||
bool queued;
|
||||
bool texture_failed;
|
||||
bool running;
|
||||
QString save_fn;
|
||||
};
|
||||
|
||||
#endif // RENDERTHREAD_H
|
||||
|
||||
+10
-23
@@ -23,7 +23,7 @@
|
||||
#include "ui/timelinewidget.h"
|
||||
#include "ui/renderfunctions.h"
|
||||
#include "ui/renderthread.h"
|
||||
#include "Ui/viewerwindow.h"
|
||||
#include "ui/viewerwindow.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QPainter>
|
||||
@@ -50,7 +50,6 @@ extern "C" {
|
||||
|
||||
ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
QOpenGLWidget(parent),
|
||||
default_fbo(nullptr),
|
||||
waveform(false),
|
||||
waveform_zoom(1.0),
|
||||
waveform_scroll(0),
|
||||
@@ -84,7 +83,7 @@ ViewerWidget::~ViewerWidget() {
|
||||
}
|
||||
|
||||
void ViewerWidget::delete_function() {
|
||||
renderer->start_render(context(), nullptr);
|
||||
closeActiveClips(viewer->seq);
|
||||
}
|
||||
|
||||
void ViewerWidget::set_waveform_scroll(int s) {
|
||||
@@ -149,22 +148,8 @@ void ViewerWidget::save_frame() {
|
||||
if (!fn.endsWith(selected_ext, Qt::CaseInsensitive)) {
|
||||
fn += selected_ext;
|
||||
}
|
||||
QOpenGLFramebufferObject fbo(viewer->seq->width, viewer->seq->height, QOpenGLFramebufferObject::CombinedDepthStencil, GL_TEXTURE_RECTANGLE);
|
||||
|
||||
rendering = true;
|
||||
fbo.bind();
|
||||
|
||||
default_fbo = &fbo;
|
||||
|
||||
paintGL();
|
||||
|
||||
QImage img(viewer->seq->width, viewer->seq->height, QImage::Format_RGBA8888);
|
||||
glReadPixels(0, 0, img.width(), img.height(), GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
img.save(fn);
|
||||
|
||||
fbo.release();
|
||||
default_fbo = nullptr;
|
||||
rendering = false;
|
||||
renderer->start_render(context(), viewer->seq, fn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,6 +164,8 @@ void ViewerWidget::fullscreen_menu_action(QAction *action) {
|
||||
QScreen* selected_screen = QGuiApplication::screens().at(action->data().toInt());
|
||||
window->showFullScreen();
|
||||
window->setGeometry(selected_screen->geometry());
|
||||
|
||||
// HACK: window seems to show with distorted texture on first showing, so we queue an update after it's shown
|
||||
QTimer::singleShot(100, window, SLOT(update()));
|
||||
}
|
||||
}
|
||||
@@ -229,7 +216,7 @@ void ViewerWidget::frame_update() {
|
||||
drawn_gizmos = false;
|
||||
force_quit = false;
|
||||
|
||||
bool render_audio = (viewer->playing || rendering);
|
||||
bool render_audio = (viewer->playing || audio_rendering);
|
||||
|
||||
// send context to other thread for drawing
|
||||
doneCurrent();
|
||||
@@ -238,7 +225,7 @@ void ViewerWidget::frame_update() {
|
||||
// render the audio
|
||||
QVector<Clip*> nests;
|
||||
bool texture_failed;
|
||||
compose_sequence(viewer, context(), viewer->seq, nests, false, render_audio, &gizmos, texture_failed);
|
||||
compose_sequence(viewer, context(), viewer->seq, nests, false, render_audio, &gizmos, texture_failed, audio_rendering);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,8 +285,8 @@ void ViewerWidget::move_gizmos(QMouseEvent *event, bool done) {
|
||||
if (selected_gizmo != nullptr) {
|
||||
double multiplier = double(viewer->seq->width) / double(width());
|
||||
|
||||
int x_movement = (event->pos().x() - drag_start_x)*multiplier;
|
||||
int y_movement = (event->pos().y() - drag_start_y)*multiplier;
|
||||
int x_movement = qRound((event->pos().x() - drag_start_x)*multiplier);
|
||||
int y_movement = qRound((event->pos().y() - drag_start_y)*multiplier);
|
||||
|
||||
gizmos->gizmo_move(selected_gizmo, x_movement, y_movement, get_timecode(gizmos->parent_clip, gizmos->parent_clip->sequence->playhead), done);
|
||||
|
||||
@@ -479,7 +466,7 @@ void ViewerWidget::paintGL() {
|
||||
|
||||
// draw title/action safe area
|
||||
|
||||
if (config.show_title_safe_area && !rendering) {
|
||||
if (config.show_title_safe_area) {
|
||||
drawTitleSafeArea();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,6 @@ public:
|
||||
Viewer* viewer;
|
||||
ViewerContainer* container;
|
||||
|
||||
QOpenGLFramebufferObject* default_fbo;
|
||||
|
||||
bool waveform;
|
||||
Clip* waveform_clip;
|
||||
const FootageStream* waveform_ms;
|
||||
|
||||
Reference in New Issue
Block a user