From 6b07adb4526907b4cea3bb48b00e195492aa17e9 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 26 Mar 2019 12:13:32 +1100 Subject: [PATCH 1/8] improved autocut silence dialog --- dialogs/autocutsilencedialog.cpp | 27 ++++++++++----------------- dialogs/autocutsilencedialog.h | 4 ++-- global/global.cpp | 2 +- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/dialogs/autocutsilencedialog.cpp b/dialogs/autocutsilencedialog.cpp index b1d801b99..9280dbe66 100644 --- a/dialogs/autocutsilencedialog.cpp +++ b/dialogs/autocutsilencedialog.cpp @@ -31,7 +31,7 @@ #include "panels/panels.h" #include "panels/timeline.h" -AutoCutSilenceDialog::AutoCutSilenceDialog(QWidget *parent, QVector clips) : +AutoCutSilenceDialog::AutoCutSilenceDialog(QWidget *parent, QVector clips) : QDialog(parent), clips_(clips) { @@ -119,10 +119,12 @@ void AutoCutSilenceDialog::accept() { } void AutoCutSilenceDialog::cut_silence() { + ComboAction* ca = new ComboAction(); + // Loop over clips provided to this dialog for (int j=0;jclips.at(clips_.at(j)).get(); // Check if this clip is an audio footage clip if (clip->track() >= 0 @@ -200,23 +202,14 @@ void AutoCutSilenceDialog::cut_silence() { } } - ComboAction* ca = new ComboAction(); - - // NO GOOD VERY BAD TEST CODE - int clip_index = -1; - for (int i=0;iclips.size();i++) { - if (olive::ActiveSequence->clips.at(i).get() == clip) { - clip_index = i; - break; - } - } - - Q_ASSERT(clip_index > -1); - - panel_timeline->split_clip_at_positions(ca, clip_index, split_positions); - olive::UndoStack.push(ca); + panel_timeline->split_clip_at_positions(ca, clips_.at(j), split_positions); } + } + if (ca->hasActions()) { + olive::UndoStack.push(ca); + } else { + delete ca; } } diff --git a/dialogs/autocutsilencedialog.h b/dialogs/autocutsilencedialog.h index 32c572e16..6f156679c 100644 --- a/dialogs/autocutsilencedialog.h +++ b/dialogs/autocutsilencedialog.h @@ -31,7 +31,7 @@ class AutoCutSilenceDialog : public QDialog { Q_OBJECT public: - AutoCutSilenceDialog(QWidget* parent, QVector clips); + AutoCutSilenceDialog(QWidget* parent, QVector clips); public slots: virtual int exec() override; private slots: @@ -39,7 +39,7 @@ private slots: private: void cut_silence(); - QVector clips_; + QVector clips_; LabelSlider* attack_threshold; LabelSlider* release_threshold; diff --git a/global/global.cpp b/global/global.cpp index 382bb3a16..9f7ada144 100644 --- a/global/global.cpp +++ b/global/global.cpp @@ -441,7 +441,7 @@ void OliveGlobal::open_speed_dialog() { void OliveGlobal::open_autocut_silence_dialog() { if (CheckForActiveSequence()) { - QVector selected_clips = olive::ActiveSequence->SelectedClips(); + QVector selected_clips = olive::ActiveSequence->SelectedClipIndexes(); if (selected_clips.isEmpty()) { QMessageBox::critical(olive::MainWindow, From 675ea942f1cb18261637e30f17eeca814a6501d3 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 26 Mar 2019 14:13:34 +1100 Subject: [PATCH 2/8] fixed #689 --- ui/mainwindow.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 5f79b151b..09747ffb5 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -1080,13 +1080,13 @@ void MainWindow::maximize_panel() { // store the current state of panels temp_panel_state = saveState(); - // remove all dock widgets (kind of painful having to do each individually) - if (focused_panel != panel_project) removeDockWidget(panel_project); - if (focused_panel != panel_effect_controls) removeDockWidget(panel_effect_controls); - if (focused_panel != panel_timeline) removeDockWidget(panel_timeline); - if (focused_panel != panel_sequence_viewer) removeDockWidget(panel_sequence_viewer); - if (focused_panel != panel_footage_viewer) removeDockWidget(panel_footage_viewer); - if (focused_panel != panel_graph_editor) removeDockWidget(panel_graph_editor); + // remove all dock widgets + for (int i=0;isetVisible(false); + olive::panels.at(i)->setFloating(true); + } + } } } else { // we must be maximized, restore previous state From 5b08914e18c19c488c95af08a64c3555d193a463 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 26 Mar 2019 14:15:21 +1100 Subject: [PATCH 3/8] more documentation on maximize panel --- ui/mainwindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 09747ffb5..495842e3c 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -1080,10 +1080,13 @@ void MainWindow::maximize_panel() { // store the current state of panels temp_panel_state = saveState(); - // remove all dock widgets + // remove all dock widgets that aren't the hovered panel for (int i=0;isetVisible(false); + + // set it to floating olive::panels.at(i)->setFloating(true); } } From 3710e68db705c1cb15aff61935117e6455586b70 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 28 Mar 2019 02:06:23 +1100 Subject: [PATCH 4/8] fixed #703 --- effects/shaders/swirl.frag | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/effects/shaders/swirl.frag b/effects/shaders/swirl.frag index e820e3394..00411f61f 100644 --- a/effects/shaders/swirl.frag +++ b/effects/shaders/swirl.frag @@ -26,6 +26,5 @@ void main(void) { tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); } tc += center; - vec3 color = texture2D(myTexture, tc / resolution).rgb; - gl_FragColor = vec4(color, 1.0); + gl_FragColor = texture2D(myTexture, tc / resolution); } \ No newline at end of file From 49093d0f5ea4b9da18fb7998a5d048036e06a191 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 28 Mar 2019 12:37:29 +1100 Subject: [PATCH 5/8] fixed #707 --- rendering/exportthread.cpp | 38 ++++++++++++-------------------------- rendering/exportthread.h | 2 +- 2 files changed, 13 insertions(+), 27 deletions(-) diff --git a/rendering/exportthread.cpp b/rendering/exportthread.cpp index 9ccf3c79f..fcbb77067 100644 --- a/rendering/exportthread.cpp +++ b/rendering/exportthread.cpp @@ -71,7 +71,7 @@ ExportThread::ExportThread(const ExportParams ¶ms, surface.create(); } -bool ExportThread::Encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, AVFrame* frame, AVPacket* packet, AVStream* stream, bool rescale) { +bool ExportThread::Encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, AVFrame* frame, AVPacket* packet, AVStream* stream) { ret = avcodec_send_frame(codec_ctx, frame); if (ret < 0) { qCritical() << "Failed to send frame to encoder." << ret; @@ -92,18 +92,9 @@ bool ExportThread::Encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, } packet->stream_index = stream->index; - if (rescale) { - if (packet->pts != AV_NOPTS_VALUE) { - packet->pts = qRound(packet->pts * av_q2d(codec_ctx->time_base) / av_q2d(stream->time_base)); - } - if (packet->dts != AV_NOPTS_VALUE) { - packet->dts = qRound(packet->dts * av_q2d(codec_ctx->time_base) / av_q2d(stream->time_base)); - } - if (packet->duration > 0) { - packet->duration = qRound(packet->duration * av_q2d(codec_ctx->time_base) / av_q2d(stream->time_base)); - } - //av_packet_rescale_ts(packet, codec_ctx->time_base, stream->time_base); - } + + av_packet_rescale_ts(packet, codec_ctx->time_base, stream->time_base); + av_interleaved_write_frame(ofmt_ctx, packet); av_packet_unref(packet); } @@ -483,7 +474,7 @@ void ExportThread::Export() sws_frame->pts = qRound(timecode_secs/av_q2d(vcodec_ctx->time_base)); // Send frame to encoder - if (!Encode(fmt_ctx, vcodec_ctx, sws_frame, &video_pkt, video_stream, true)) { + if (!Encode(fmt_ctx, vcodec_ctx, sws_frame, &video_pkt, video_stream)) { return; } @@ -521,7 +512,7 @@ void ExportThread::Export() swr_frame->pts = file_audio_samples; // Send frame to encoder - if (!Encode(fmt_ctx, acodec_ctx, swr_frame, &audio_pkt, audio_stream, true)) { + if (!Encode(fmt_ctx, acodec_ctx, swr_frame, &audio_pkt, audio_stream)) { return; } @@ -570,7 +561,7 @@ void ExportThread::Export() swr_convert_frame(swr_ctx, swr_frame, nullptr); if (swr_frame->nb_samples == 0) break; swr_frame->pts = file_audio_samples; - if (!Encode(fmt_ctx, acodec_ctx, swr_frame, &audio_pkt, audio_stream, true)) { + if (!Encode(fmt_ctx, acodec_ctx, swr_frame, &audio_pkt, audio_stream)) { return; } file_audio_samples += swr_frame->nb_samples; @@ -583,17 +574,12 @@ void ExportThread::Export() return; } - bool continueVideo = params_.video_enabled; - bool continueAudio = params_.audio_enabled; - // Flush remaining packets out of video and audio encoders - while (continueVideo && continueAudio) { - if (continueVideo) { - continueVideo = Encode(fmt_ctx, vcodec_ctx, nullptr, &video_pkt, video_stream, true); - } - if (continueAudio) { - continueAudio = Encode(fmt_ctx, acodec_ctx, nullptr, &audio_pkt, audio_stream, true); - } + if (params_.video_enabled) { + Encode(fmt_ctx, vcodec_ctx, nullptr, &video_pkt, video_stream); + } + if (params_.audio_enabled) { + Encode(fmt_ctx, acodec_ctx, nullptr, &audio_pkt, audio_stream); } // Write container trailer diff --git a/rendering/exportthread.h b/rendering/exportthread.h index e4bc03080..3db7288ed 100644 --- a/rendering/exportthread.h +++ b/rendering/exportthread.h @@ -83,7 +83,7 @@ signals: public slots: void Interrupt(); private: - bool Encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, AVFrame* frame, AVPacket* packet, AVStream* stream, bool rescale); + bool Encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, AVFrame* frame, AVPacket* packet, AVStream* stream); bool SetupVideo(); bool SetupAudio(); bool SetupContainer(); From 1adca7f2cc1255beca70c89c1a2053e0014a2358 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 28 Mar 2019 13:07:48 +1100 Subject: [PATCH 6/8] restored radius setting to gaussian blur, fixes #702 --- effects/shaders/gaussianblur.frag | 6 +++--- effects/shaders/gaussianblur.xml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/effects/shaders/gaussianblur.frag b/effects/shaders/gaussianblur.frag index 80aaedb18..da83e1389 100644 --- a/effects/shaders/gaussianblur.frag +++ b/effects/shaders/gaussianblur.frag @@ -4,7 +4,7 @@ uniform sampler2D image; -// uniform float radius; +uniform float radius; uniform float sigma; uniform vec2 resolution; uniform bool horiz_blur; @@ -22,13 +22,13 @@ float gaussian2(float x, float y, float sigma) { } void main(void) { - float rad = ceil(sigma); + float rad = ceil(radius); float sum = 0.0; vec4 color = vec4(0.0); - bool radius_is_zero = (rad == 0.0); + bool radius_is_zero = (rad == 0.0 || sigma == 0.0); if (!radius_is_zero) { for (float x=-rad+0.5;x<=rad;x+=2.0) { diff --git a/effects/shaders/gaussianblur.xml b/effects/shaders/gaussianblur.xml index d0d669f6d..def19b73e 100644 --- a/effects/shaders/gaussianblur.xml +++ b/effects/shaders/gaussianblur.xml @@ -1,8 +1,8 @@ - + From c468d023b01dbabbb1ff9b42319c158bb14937be Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 28 Mar 2019 13:34:58 +1100 Subject: [PATCH 7/8] mathematically calculate gaussian blur radius --- effects/shaders/gaussianblur.frag | 4 ++-- effects/shaders/gaussianblur.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/effects/shaders/gaussianblur.frag b/effects/shaders/gaussianblur.frag index da83e1389..720671d99 100644 --- a/effects/shaders/gaussianblur.frag +++ b/effects/shaders/gaussianblur.frag @@ -4,7 +4,7 @@ uniform sampler2D image; -uniform float radius; +//uniform float radius; uniform float sigma; uniform vec2 resolution; uniform bool horiz_blur; @@ -22,7 +22,7 @@ float gaussian2(float x, float y, float sigma) { } void main(void) { - float rad = ceil(radius); + float rad = ceil(3.0 * sigma); float sum = 0.0; diff --git a/effects/shaders/gaussianblur.xml b/effects/shaders/gaussianblur.xml index def19b73e..d0d669f6d 100644 --- a/effects/shaders/gaussianblur.xml +++ b/effects/shaders/gaussianblur.xml @@ -1,8 +1,8 @@ - + From 4e0188fd3a0d280c89820b45fa43ff158d7ed618 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 28 Mar 2019 18:21:35 +1100 Subject: [PATCH 8/8] enforce trilinear and mipmap generation --- effects/effect.cpp | 4 +++- rendering/exportthread.cpp | 2 +- rendering/framebufferobject.cpp | 22 ++++++++++++---------- rendering/renderfunctions.cpp | 14 +++++++++++--- timeline/clip.cpp | 2 +- ui/viewerwidget.cpp | 4 +++- ui/viewerwindow.cpp | 2 +- 7 files changed, 32 insertions(+), 18 deletions(-) diff --git a/effects/effect.cpp b/effects/effect.cpp index 5fbff641f..7aca89711 100644 --- a/effects/effect.cpp +++ b/effects/effect.cpp @@ -805,7 +805,9 @@ void Effect::startEffect() { } void Effect::endEffect() { - if (bound) glslProgram->release(); + if (bound) { + glslProgram->release(); + } bound = false; } diff --git a/rendering/exportthread.cpp b/rendering/exportthread.cpp index fcbb77067..239f22b2b 100644 --- a/rendering/exportthread.cpp +++ b/rendering/exportthread.cpp @@ -574,7 +574,7 @@ void ExportThread::Export() return; } - // Flush remaining packets out of video and audio encoders + // Flush remaining packets out of video and audio encoders by sending a null frame if (params_.video_enabled) { Encode(fmt_ctx, vcodec_ctx, nullptr, &video_pkt, video_stream); } diff --git a/rendering/framebufferobject.cpp b/rendering/framebufferobject.cpp index 10a2cbb96..b9585400b 100644 --- a/rendering/framebufferobject.cpp +++ b/rendering/framebufferobject.cpp @@ -26,37 +26,39 @@ void FramebufferObject::Create(QOpenGLContext *ctx, int width, int height) // set context to new context provided ctx_ = ctx; + QOpenGLFunctions* f = ctx->functions(); + // create framebuffer object - ctx->functions()->glGenFramebuffers(1, &buffer_); + f->glGenFramebuffers(1, &buffer_); // create texture - ctx->functions()->glGenTextures(1, &texture_); + f->glGenTextures(1, &texture_); // bind framebuffer for attaching - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer_); + f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer_); // bind texture - ctx->functions()->glBindTexture(GL_TEXTURE_2D, texture_); + f->glBindTexture(GL_TEXTURE_2D, texture_); // allocate storage for texture - ctx->functions()->glTexImage2D( + f->glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr ); // set texture filtering to bilinear - ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // attach texture to framebuffer - ctx->functions()->glFramebufferTexture2D( + f->glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0 ); // release texture - ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0); + f->glBindTexture(GL_TEXTURE_2D, 0); // release framebuffer - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } void FramebufferObject::Destroy() diff --git a/rendering/renderfunctions.cpp b/rendering/renderfunctions.cpp index 48cfc1a84..25db7e8f9 100644 --- a/rendering/renderfunctions.cpp +++ b/rendering/renderfunctions.cpp @@ -51,7 +51,17 @@ namespace OCIO = OCIO_NAMESPACE; #include "panels/timeline.h" #include "panels/viewer.h" +void PrepareToDraw(QOpenGLFunctions* f) { + f->glGenerateMipmap(GL_TEXTURE_2D); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); +} + void full_blit() { + PrepareToDraw(QOpenGLContext::currentContext()->functions()); + glPushMatrix(); glLoadIdentity(); glOrtho(0, 1, 0, 1, -1, 1); @@ -484,9 +494,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) { glBindTexture(GL_TEXTURE_2D, textureID); // set texture filter to bilinear - params.ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D); - params.ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - params.ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + PrepareToDraw(params.ctx->functions()); // draw clip on screen according to gl coordinates glBegin(GL_QUADS); diff --git a/timeline/clip.cpp b/timeline/clip.cpp index 743587f79..1caaf70d1 100644 --- a/timeline/clip.cpp +++ b/timeline/clip.cpp @@ -574,7 +574,7 @@ bool Clip::Retrieve() texture->setFormat(QOpenGLTexture::RGBA8_UNorm); texture->setMipLevels(texture->maximumMipLevels()); - texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); + texture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear); texture->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8); } diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 5847eaa32..b00081370 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -548,7 +548,7 @@ void ViewerWidget::paintGL() { makeCurrent(); // clear to solid black - glClearColor(0.0, 0.0, 0.0, 1.0); + glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); // set color multipler to straight white @@ -564,6 +564,8 @@ void ViewerWidget::paintGL() { glBindTexture(GL_TEXTURE_2D, tex); + context()->functions()->glGenerateMipmap(GL_TEXTURE_2D); + glBegin(GL_QUADS); double zoom_factor = container->zoom/(double(width())/double(viewer->seq->width)); diff --git a/ui/viewerwindow.cpp b/ui/viewerwindow.cpp index 646db81f9..a73b4cb76 100644 --- a/ui/viewerwindow.cpp +++ b/ui/viewerwindow.cpp @@ -111,7 +111,7 @@ void ViewerWindow::paintGL() { if (texture > 0) { if (mutex != nullptr) mutex->lock(); - glClearColor(0.0, 0.0, 0.0, 1.0); + glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D);