From 0580fce9815f782d976223312cc19441602a31f5 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 16 Jan 2019 21:23:23 +1100 Subject: [PATCH] work towards exports working on threaded gl --- dialogs/exportdialog.cpp | 120 +++++++++++++++++++-------------------- io/exportthread.cpp | 23 ++------ mainwindow.cpp | 11 +++- mainwindow.h | 4 +- playback/audio.cpp | 3 +- playback/audio.h | 3 +- playback/playback.h | 2 - ui/renderfunctions.cpp | 7 ++- ui/renderfunctions.h | 4 +- ui/renderthread.cpp | 32 +++++++---- ui/renderthread.h | 3 +- ui/viewerwidget.cpp | 33 ++++------- ui/viewerwidget.h | 2 - 13 files changed, 121 insertions(+), 126 deletions(-) diff --git a/dialogs/exportdialog.cpp b/dialogs/exportdialog.cpp index d5c52e8fb..b012f506b 100644 --- a/dialogs/exportdialog.cpp +++ b/dialogs/exportdialog.cpp @@ -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); diff --git a/io/exportthread.cpp b/io/exportthread.cpp index 0931b12f3..bd4de4ba8 100644 --- a/io/exportthread.cpp +++ b/io/exportthread.cpp @@ -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; } diff --git a/mainwindow.cpp b/mainwindow.cpp index 59871a4ca..9e7b99233 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -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"; } diff --git a/mainwindow.h b/mainwindow.h index 490c75097..42b5b8ea8 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -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(); diff --git a/playback/audio.cpp b/playback/audio.cpp index 8655ab12b..19e2f656f 100644 --- a/playback/audio.cpp +++ b/playback/audio.cpp @@ -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) { diff --git a/playback/audio.h b/playback/audio.h index 081a92e78..c2836a6f0 100644 --- a/playback/audio.h +++ b/playback/audio.h @@ -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 diff --git a/playback/playback.h b/playback/playback.h index df81c1183..2c0a6cd17 100644 --- a/playback/playback.h +++ b/playback/playback.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); diff --git a/ui/renderfunctions.cpp b/ui/renderfunctions.cpp index ffd8a4f74..e44e44516 100644 --- a/ui/renderfunctions.cpp +++ b/ui/renderfunctions.cpp @@ -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()) { diff --git a/ui/renderfunctions.h b/ui/renderfunctions.h index 56af7d3ff..a44dbc9e7 100644 --- a/ui/renderfunctions.h +++ b/ui/renderfunctions.h @@ -15,6 +15,8 @@ GLuint compose_sequence(Viewer* viewer, QVector& nests, bool video, bool render_audio, - Effect **gizmos, bool &texture_failed); + Effect **gizmos, + bool &texture_failed, + bool rendering); #endif // RENDERFUNCTIONS_H diff --git a/ui/renderthread.cpp b/ui/renderthread.cpp index 9039ca423..21dc7dbd4 100644 --- a/ui/renderthread.cpp +++ b/ui/renderthread.cpp @@ -109,20 +109,33 @@ void RenderThread::paint() { Effect* gizmos; // does nothing yet QVector 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() { diff --git a/ui/renderthread.h b/ui/renderthread.h index 0bfd2033a..bc94e48b9 100644 --- a/ui/renderthread.h +++ b/ui/renderthread.h @@ -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 diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index c917bb43d..8f7216247 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -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 @@ -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 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(); } diff --git a/ui/viewerwidget.h b/ui/viewerwidget.h index 8e030bdb2..43bcc9714 100644 --- a/ui/viewerwidget.h +++ b/ui/viewerwidget.h @@ -35,8 +35,6 @@ public: Viewer* viewer; ViewerContainer* container; - QOpenGLFramebufferObject* default_fbo; - bool waveform; Clip* waveform_clip; const FootageStream* waveform_ms;