From 5afd135796fdfbbf59f1e7910c9adcb816ea316b Mon Sep 17 00:00:00 2001 From: Jonathan Noble Date: Sat, 19 Jan 2019 15:30:35 +0000 Subject: [PATCH 1/3] Fix memory leak from using libavcodec api (cherry picked from commit 8c7eb8997660a70e1e58a4f89a82574931195e63) Sequence class encapsulation work. Memory leak fixes work (cherry picked from commit 7caaa778697ea2a84162f4ce523be8b6cef79647) --- io/previewgenerator.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index 01ea6e548..621a6b3ff 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -1,4 +1,4 @@ -#include "previewgenerator.h" +#include "previewgenerator.h" #include "project/media.h" #include "project/footage.h" @@ -277,7 +277,7 @@ void PreviewGenerator::generate_waveform() { if (!s->preview_done) { int dstH = 120; int dstW = dstH * ((float)temp_frame->width/(float)temp_frame->height); - uint8_t* data = new uint8_t[dstW*dstH*4]; + uint8_t* imgData = new uint8_t[dstW*dstH*4]; sws_ctx = sws_getContext( temp_frame->width, @@ -294,9 +294,9 @@ void PreviewGenerator::generate_waveform() { int linesize[AV_NUM_DATA_POINTERS]; linesize[0] = dstW*4; - sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &data, linesize); + sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &imgData, linesize); - s->video_preview = QImage(data, dstW, dstH, linesize[0], QImage::Format_RGBA8888); + s->video_preview = QImage(imgData, dstW, dstH, linesize[0], QImage::Format_RGBA8888); s->make_square_thumb(); // is video interlaced? @@ -311,6 +311,8 @@ void PreviewGenerator::generate_waveform() { avcodec_close(codec_ctx[packet->stream_index]); codec_ctx[packet->stream_index] = nullptr; } + + delete[] imgData; } media_lengths[packet->stream_index]++; } else if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -415,7 +417,10 @@ void PreviewGenerator::generate_waveform() { finalize_media(); } delete [] media_lengths; - delete [] codec_ctx; + + if (codec_ctx != NULL) { + avcodec_free_context(codec_ctx); + } } QString PreviewGenerator::get_thumbnail_path(const QString& hash, const FootageStream& ms) { From 52c2fee1420aaff7d1b21c1ae78f0426febf1240 Mon Sep 17 00:00:00 2001 From: Jonathan Noble Date: Fri, 25 Jan 2019 23:33:00 +0000 Subject: [PATCH 2/3] Fixed the use of float as loop counter --- ui/renderfunctions.cpp | 774 +++++++++++++++++++++-------------------- 1 file changed, 389 insertions(+), 385 deletions(-) diff --git a/ui/renderfunctions.cpp b/ui/renderfunctions.cpp index bbab2bd2b..efa206721 100644 --- a/ui/renderfunctions.cpp +++ b/ui/renderfunctions.cpp @@ -25,468 +25,472 @@ #include "panels/viewer.h" extern "C" { - #include +#include } //#define GL_DEFAULT_BLEND glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE) #define GL_DEFAULT_BLEND glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE) GLuint draw_clip(QOpenGLContext* ctx, QOpenGLFramebufferObject* fbo, GLuint texture, bool clear) { - glPushMatrix(); - glLoadIdentity(); - glOrtho(0, 1, 0, 1, -1, 1); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, 1, 0, 1, -1, 1); - GLint current_fbo = 0; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + GLint current_fbo = 0; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); - fbo->bind(); + fbo->bind(); - if (clear) glClear(GL_COLOR_BUFFER_BIT); + if (clear) glClear(GL_COLOR_BUFFER_BIT); - // get current blend mode - GLint src_rgb, src_alpha, dst_rgb, dst_alpha; - glGetIntegerv(GL_BLEND_SRC_RGB, &src_rgb); - glGetIntegerv(GL_BLEND_SRC_ALPHA, &src_alpha); - glGetIntegerv(GL_BLEND_DST_RGB, &dst_rgb); - glGetIntegerv(GL_BLEND_DST_ALPHA, &dst_alpha); + // get current blend mode + GLint src_rgb, src_alpha, dst_rgb, dst_alpha; + glGetIntegerv(GL_BLEND_SRC_RGB, &src_rgb); + glGetIntegerv(GL_BLEND_SRC_ALPHA, &src_alpha); + glGetIntegerv(GL_BLEND_DST_RGB, &dst_rgb); + glGetIntegerv(GL_BLEND_DST_ALPHA, &dst_alpha); - ctx->functions()->GL_DEFAULT_BLEND; + ctx->functions()->GL_DEFAULT_BLEND; - glBindTexture(GL_TEXTURE_2D, texture); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); // top left - glVertex2f(0, 0); // top left - glTexCoord2f(1, 0); // top right - glVertex2f(1, 0); // top right - glTexCoord2f(1, 1); // bottom right - glVertex2f(1, 1); // bottom right - glTexCoord2f(0, 1); // bottom left - glVertex2f(0, 1); // bottom left - glEnd(); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, texture); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); // top left + glVertex2f(0, 0); // top left + glTexCoord2f(1, 0); // top right + glVertex2f(1, 0); // top right + glTexCoord2f(1, 1); // bottom right + glVertex2f(1, 1); // bottom right + glTexCoord2f(0, 1); // bottom left + glVertex2f(0, 1); // bottom left + glEnd(); + glBindTexture(GL_TEXTURE_2D, 0); -// fbo->release(); - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); + // fbo->release(); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); - // restore previous blendFunc - ctx->functions()->glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); + // restore previous blendFunc + ctx->functions()->glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); - //if (default_fbo != nullptr) default_fbo->bind(); + //if (default_fbo != nullptr) default_fbo->bind(); - glPopMatrix(); - return fbo->texture(); + glPopMatrix(); + return fbo->texture(); } void process_effect(QOpenGLContext* ctx, - Clip* c, - Effect* e, - double timecode, - GLTextureCoords& coords, - GLuint& composite_texture, - bool& fbo_switcher, - bool& texture_failed, - int data) { - if (e->is_enabled()) { - if (e->enable_coords) { - e->process_coords(timecode, coords, data); - } - if ((e->enable_shader && shaders_are_enabled) || e->enable_superimpose) { - e->startEffect(); - if ((e->enable_shader && shaders_are_enabled) && e->is_glsl_linked()) { - e->process_shader(timecode, coords); - composite_texture = draw_clip(ctx, c->fbo[fbo_switcher], composite_texture, true); - fbo_switcher = !fbo_switcher; - } - if (e->enable_superimpose) { - GLuint superimpose_texture = e->process_superimpose(timecode); - if (superimpose_texture == 0) { - qWarning() << "Superimpose texture was nullptr, retrying..."; - texture_failed = true; - } else { - composite_texture = draw_clip(ctx, c->fbo[!fbo_switcher], superimpose_texture, false); - } - } - e->endEffect(); - } - } + Clip* c, + Effect* e, + double timecode, + GLTextureCoords& coords, + GLuint& composite_texture, + bool& fbo_switcher, + bool& texture_failed, + int data) { + if (e->is_enabled()) { + if (e->enable_coords) { + e->process_coords(timecode, coords, data); + } + if ((e->enable_shader && shaders_are_enabled) || e->enable_superimpose) { + e->startEffect(); + if ((e->enable_shader && shaders_are_enabled) && e->is_glsl_linked()) { + e->process_shader(timecode, coords); + composite_texture = draw_clip(ctx, c->fbo[fbo_switcher], composite_texture, true); + fbo_switcher = !fbo_switcher; + } + if (e->enable_superimpose) { + GLuint superimpose_texture = e->process_superimpose(timecode); + if (superimpose_texture == 0) { + qWarning() << "Superimpose texture was nullptr, retrying..."; + texture_failed = true; + } else { + composite_texture = draw_clip(ctx, c->fbo[!fbo_switcher], superimpose_texture, false); + } + } + e->endEffect(); + } + } } GLuint compose_sequence(Viewer* viewer, - QOpenGLContext* ctx, - Sequence* seq, - QVector& nests, - bool video, - bool render_audio, - Effect** gizmos, - bool& texture_failed, - bool rendering, - int playback_speed) { - GLint current_fbo = 0; - if (video) { - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); - } + QOpenGLContext* ctx, + Sequence* seq, + QVector& nests, + bool video, + bool render_audio, + Effect** gizmos, + bool& texture_failed, + bool rendering, + int playback_speed) { + GLint current_fbo = 0; + if (video) { + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + } - Sequence* s = seq; - long playhead = s->playhead; + Sequence* s = seq; + long playhead = s->playhead; - if (!nests.isEmpty()) { - for (int i=0;imedia->to_sequence(); - playhead += nests.at(i)->clip_in - nests.at(i)->get_timeline_in_with_transition(); - playhead = refactor_frame_number(playhead, nests.at(i)->sequence->frame_rate, s->frame_rate); - } + if (!nests.isEmpty()) { + for (int i=0;imedia->to_sequence(); + playhead += nests.at(i)->clip_in - nests.at(i)->get_timeline_in_with_transition(); + playhead = refactor_frame_number(playhead, nests.at(i)->sequence->frame_rate, s->frame_rate); + } - if (video && nests.last()->fbo != nullptr) { - nests.last()->fbo[0]->bind(); - glClear(GL_COLOR_BUFFER_BIT); -// nests.last()->fbo[0]->release(); - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); - } - } + if (video && nests.last()->fbo != nullptr) { + nests.last()->fbo[0]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + // nests.last()->fbo[0]->release(); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); + } + } - int audio_track_count = 0; + int audio_track_count = 0; - QVector current_clips; + QVector current_clips; - for (int i=0;iclips.size();i++) { - Clip* c = s->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = s->clips.at(i); - // if clip starts within one second and/or hasn't finished yet - if (c != nullptr) { -// if (!(!nests.isEmpty() && !same_sign(c->track, nests.last()->track))) { - if ((c->track < 0) == video) { - bool clip_is_active = false; + // if clip starts within one second and/or hasn't finished yet + if (c != nullptr) { + // if (!(!nests.isEmpty() && !same_sign(c->track, nests.last()->track))) { + if ((c->track < 0) == video) { + bool clip_is_active = false; - if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = c->media->to_footage(); - if (!m->invalid && !(c->track >= 0 && !is_audio_device_set())) { - if (m->ready) { - const FootageStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream); - if (ms != nullptr && is_clip_active(c, playhead)) { - // if thread is already working, we don't want to touch this, - // but we also don't want to hang the UI thread - if (!c->open) { - open_clip(c, !rendering); - } - clip_is_active = true; - if (c->track >= 0) audio_track_count++; - } else if (c->finished_opening) { - close_clip(c, false); - } - } else { - //qWarning() << "Media '" + m->name + "' was not ready, retrying..."; - texture_failed = true; - } - } - } else { - if (is_clip_active(c, playhead)) { - if (!c->open) open_clip(c, !rendering); - clip_is_active = true; - } else if (c->finished_opening) { - close_clip(c, false); - } - } - if (clip_is_active) { - bool added = false; - for (int j=0;jtrack < c->track) { - current_clips.insert(j, c); - added = true; - break; - } - } - if (!added) { - current_clips.append(c); - } - } - } - } - } + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + Footage* m = c->media->to_footage(); + if (!m->invalid && !(c->track >= 0 && !is_audio_device_set())) { + if (m->ready) { + const FootageStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream); + if (ms != nullptr && is_clip_active(c, playhead)) { + // if thread is already working, we don't want to touch this, + // but we also don't want to hang the UI thread + if (!c->open) { + open_clip(c, !rendering); + } + clip_is_active = true; + if (c->track >= 0) audio_track_count++; + } else if (c->finished_opening) { + close_clip(c, false); + } + } else { + //qWarning() << "Media '" + m->name + "' was not ready, retrying..."; + texture_failed = true; + } + } + } else { + if (is_clip_active(c, playhead)) { + if (!c->open) open_clip(c, !rendering); + clip_is_active = true; + } else if (c->finished_opening) { + close_clip(c, false); + } + } + if (clip_is_active) { + bool added = false; + for (int j=0;jtrack < c->track) { + current_clips.insert(j, c); + added = true; + break; + } + } + if (!added) { + current_clips.append(c); + } + } + } + } + } - int half_width = s->width/2; - int half_height = s->height/2; + int half_width = s->width/2; + int half_height = s->height/2; - if (video) { - glPushMatrix(); - glLoadIdentity(); - glOrtho(-half_width, half_width, -half_height, half_height, -1, 10); - } + if (video) { + glPushMatrix(); + glLoadIdentity(); + glOrtho(-half_width, half_width, -half_height, half_height, -1, 10); + } - for (int i=0;imedia != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->finished_opening) { - qWarning() << "Tried to display clip" << i << "but it's closed"; - texture_failed = true; - } else { - if (c->track < 0) { - ctx->functions()->GL_DEFAULT_BLEND; - glColor4f(1.0, 1.0, 1.0, 1.0); + if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->finished_opening) { + qWarning() << "Tried to display clip" << i << "but it's closed"; + texture_failed = true; + } else { + if (c->track < 0) { + ctx->functions()->GL_DEFAULT_BLEND; + glColor4f(1.0, 1.0, 1.0, 1.0); - GLuint textureID = 0; - int video_width = c->getWidth(); - int video_height = c->getHeight(); + GLuint textureID = 0; + int video_width = c->getWidth(); + int video_height = c->getHeight(); - if (c->media != nullptr) { - switch (c->media->get_type()) { - case MEDIA_TYPE_FOOTAGE: - // set up opengl texture - if (c->texture == nullptr) { - c->texture = new QOpenGLTexture(QOpenGLTexture::Target2D); - c->texture->setSize(c->stream->codecpar->width, c->stream->codecpar->height); - c->texture->setFormat(get_gl_tex_fmt_from_av(c->pix_fmt)); - c->texture->setMipLevels(c->texture->maximumMipLevels()); - c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); - c->texture->allocateStorage(get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8); - } - get_clip_frame(c, qMax(playhead, c->timeline_in), texture_failed); - textureID = c->texture->textureId(); - break; - case MEDIA_TYPE_SEQUENCE: - textureID = -1; - break; - } - } + if (c->media != nullptr) { + switch (c->media->get_type()) { + case MEDIA_TYPE_FOOTAGE: + // set up opengl texture + if (c->texture == nullptr) { + c->texture = new QOpenGLTexture(QOpenGLTexture::Target2D); + c->texture->setSize(c->stream->codecpar->width, c->stream->codecpar->height); + c->texture->setFormat(get_gl_tex_fmt_from_av(c->pix_fmt)); + c->texture->setMipLevels(c->texture->maximumMipLevels()); + c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); + c->texture->allocateStorage(get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8); + } + get_clip_frame(c, qMax(playhead, c->timeline_in), texture_failed); + textureID = c->texture->textureId(); + break; + case MEDIA_TYPE_SEQUENCE: + textureID = -1; + break; + } + } - if (textureID == 0 && c->media != nullptr) { - qWarning() << "Texture hasn't been created yet"; - texture_failed = true; - } else if (playhead >= c->get_timeline_in_with_transition()) { - glPushMatrix(); + if (textureID == 0 && c->media != nullptr) { + qWarning() << "Texture hasn't been created yet"; + texture_failed = true; + } else if (playhead >= c->get_timeline_in_with_transition()) { + glPushMatrix(); - // start preparing cache - if (c->fbo == nullptr) { - c->fbo = new QOpenGLFramebufferObject* [2]; - c->fbo[0] = new QOpenGLFramebufferObject(video_width, video_height); - c->fbo[1] = new QOpenGLFramebufferObject(video_width, video_height); - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); - } + // start preparing cache + if (c->fbo == nullptr) { + c->fbo = new QOpenGLFramebufferObject* [2]; + c->fbo[0] = new QOpenGLFramebufferObject(video_width, video_height); + c->fbo[1] = new QOpenGLFramebufferObject(video_width, video_height); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); + } - // clear fbos - /*c->fbo[0]->bind(); - glClear(GL_COLOR_BUFFER_BIT); - c->fbo[0]->release(); - c->fbo[1]->bind(); - glClear(GL_COLOR_BUFFER_BIT); - c->fbo[1]->release();*/ + // clear fbos + /*c->fbo[0]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + c->fbo[0]->release(); + c->fbo[1]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + c->fbo[1]->release();*/ - bool fbo_switcher = false; + bool fbo_switcher = false; - glViewport(0, 0, video_width, video_height); + glViewport(0, 0, video_width, video_height); - GLuint composite_texture; + GLuint composite_texture; - if (c->media == nullptr) { - c->fbo[fbo_switcher]->bind(); - glClear(GL_COLOR_BUFFER_BIT); -// c->fbo[fbo_switcher]->release(); - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); - composite_texture = c->fbo[fbo_switcher]->texture(); - } else { - // 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, rendering, false); - nests.removeLast(); - fbo_switcher = true; - } + if (c->media == nullptr) { + c->fbo[fbo_switcher]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + // c->fbo[fbo_switcher]->release(); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); + composite_texture = c->fbo[fbo_switcher]->texture(); + } else { + // 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, rendering, false); + nests.removeLast(); + fbo_switcher = true; + } - composite_texture = draw_clip(ctx, c->fbo[fbo_switcher], textureID, true); - } + composite_texture = draw_clip(ctx, c->fbo[fbo_switcher], textureID, true); + } - fbo_switcher = !fbo_switcher; + fbo_switcher = !fbo_switcher; - // set up default coords - GLTextureCoords coords; - coords.grid_size = 1; - coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2; - coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2; - coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2; - coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; - coords.vertexBottomLeftZ = coords.vertexBottomRightZ = coords.vertexTopLeftZ = coords.vertexTopRightZ = 1; - coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0.0; - coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0; - coords.textureTopLeftQ = coords.textureTopRightQ = coords.textureTopLeftQ = coords.textureBottomLeftQ = 1; + // set up default coords + GLTextureCoords coords; + coords.grid_size = 1; + coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2; + coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2; + coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2; + coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; + coords.vertexBottomLeftZ = coords.vertexBottomRightZ = coords.vertexTopLeftZ = coords.vertexTopRightZ = 1; + coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0.0; + coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0; + coords.textureTopLeftQ = coords.textureTopRightQ = coords.textureTopLeftQ = coords.textureBottomLeftQ = 1; - // set up autoscale - if (c->autoscale && (video_width != s->width && video_height != s->height)) { - float width_multiplier = float(s->width) / float(video_width); - float height_multiplier = float(s->height) / float(video_height); - float scale_multiplier = qMin(width_multiplier, height_multiplier); - glScalef(scale_multiplier, scale_multiplier, 1); - } + // set up autoscale + if (c->autoscale && (video_width != s->width && video_height != s->height)) { + float width_multiplier = float(s->width) / float(video_width); + float height_multiplier = float(s->height) / float(video_height); + float scale_multiplier = qMin(width_multiplier, height_multiplier); + glScalef(scale_multiplier, scale_multiplier, 1); + } - // EFFECT CODE START - double timecode = get_timecode(c, playhead); + // EFFECT CODE START + double timecode = get_timecode(c, playhead); - Effect* first_gizmo_effect = nullptr; - Effect* selected_effect = nullptr; + Effect* first_gizmo_effect = nullptr; + Effect* selected_effect = nullptr; - for (int j=0;jeffects.size();j++) { - Effect* e = c->effects.at(j); - process_effect(ctx, c, e, timecode, coords, composite_texture, fbo_switcher, texture_failed, TA_NO_TRANSITION); + for (int j=0;jeffects.size();j++) { + Effect* e = c->effects.at(j); + process_effect(ctx, c, e, timecode, coords, composite_texture, fbo_switcher, texture_failed, TA_NO_TRANSITION); - if (e->are_gizmos_enabled()) { - if (first_gizmo_effect == nullptr) first_gizmo_effect = e; - if (e->container->selected) selected_effect = e; - } - } + if (e->are_gizmos_enabled()) { + if (first_gizmo_effect == nullptr) first_gizmo_effect = e; + if (e->container->selected) selected_effect = e; + } + } - if (selected_effect != nullptr) { - (*gizmos) = selected_effect; - } else if (is_clip_selected(c, true)) { - (*gizmos) = first_gizmo_effect; - } + if (selected_effect != nullptr) { + (*gizmos) = selected_effect; + } else if (is_clip_selected(c, true)) { + (*gizmos) = first_gizmo_effect; + } - if (c->get_opening_transition() != nullptr) { - int transition_progress = playhead - c->get_timeline_in_with_transition(); - if (transition_progress < c->get_opening_transition()->get_length()) { - process_effect(ctx, c, c->get_opening_transition(), (double)transition_progress/(double)c->get_opening_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_OPENING_TRANSITION); - } - } + if (c->get_opening_transition() != nullptr) { + int transition_progress = playhead - c->get_timeline_in_with_transition(); + if (transition_progress < c->get_opening_transition()->get_length()) { + process_effect(ctx, c, c->get_opening_transition(), (double)transition_progress/(double)c->get_opening_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_OPENING_TRANSITION); + } + } - if (c->get_closing_transition() != nullptr) { - int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length()); - if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { - process_effect(ctx, c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_CLOSING_TRANSITION); - } - } - // EFFECT CODE END + if (c->get_closing_transition() != nullptr) { + int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length()); + if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { + process_effect(ctx, c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_CLOSING_TRANSITION); + } + } + // EFFECT CODE END - if (!nests.isEmpty()) { - nests.last()->fbo[0]->bind(); - } - glViewport(0, 0, s->width, s->height); + if (!nests.isEmpty()) { + nests.last()->fbo[0]->bind(); + } + glViewport(0, 0, s->width, s->height); - glBindTexture(GL_TEXTURE_2D, composite_texture); + glBindTexture(GL_TEXTURE_2D, composite_texture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBegin(GL_QUADS); + glBegin(GL_QUADS); - if (coords.grid_size <= 1) { - float z = 0.0f; + if (coords.grid_size <= 1) { + float z = 0.0f; - glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left - glVertex3f(coords.vertexTopLeftX, coords.vertexTopLeftY, z); // top left - glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right - glVertex3f(coords.vertexTopRightX, coords.vertexTopRightY, z); // top right - glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right - glVertex3f(coords.vertexBottomRightX, coords.vertexBottomRightY, z); // bottom right - glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left - glVertex3f(coords.vertexBottomLeftX, coords.vertexBottomLeftY, z); // bottom left - } else { - float rows = coords.grid_size; - float cols = coords.grid_size; + glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left + glVertex3f(coords.vertexTopLeftX, coords.vertexTopLeftY, z); // top left + glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right + glVertex3f(coords.vertexTopRightX, coords.vertexTopRightY, z); // top right + glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right + glVertex3f(coords.vertexBottomRightX, coords.vertexBottomRightY, z); // bottom right + glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left + glVertex3f(coords.vertexBottomLeftX, coords.vertexBottomLeftY, z); // bottom left + } else { + const auto rows = coords.grid_size; + const auto cols = coords.grid_size; - for (float k=0;k(k)/rows; + auto next_row_prog = static_cast(k+1)/rows; + for (auto j=0; j(j)/cols; + const auto next_col_prog = static_cast(j+1)/cols; - float vertexTLX = float_lerp(coords.vertexTopLeftX, coords.vertexBottomLeftX, row_prog); - float vertexTRX = float_lerp(coords.vertexTopRightX, coords.vertexBottomRightX, row_prog); - float vertexBLX = float_lerp(coords.vertexTopLeftX, coords.vertexBottomLeftX, next_row_prog); - float vertexBRX = float_lerp(coords.vertexTopRightX, coords.vertexBottomRightX, next_row_prog); + const auto vertexTLX = float_lerp(coords.vertexTopLeftX, coords.vertexBottomLeftX, row_prog); + const auto vertexTRX = float_lerp(coords.vertexTopRightX, coords.vertexBottomRightX, row_prog); + const auto vertexBLX = float_lerp(coords.vertexTopLeftX, coords.vertexBottomLeftX, next_row_prog); + const auto vertexBRX = float_lerp(coords.vertexTopRightX, coords.vertexBottomRightX, next_row_prog); - float vertexTLY = float_lerp(coords.vertexTopLeftY, coords.vertexTopRightY, col_prog); - float vertexTRY = float_lerp(coords.vertexTopLeftY, coords.vertexTopRightY, next_col_prog); - float vertexBLY = float_lerp(coords.vertexBottomLeftY, coords.vertexBottomRightY, col_prog); - float vertexBRY = float_lerp(coords.vertexBottomLeftY, coords.vertexBottomRightY, next_col_prog); + const auto vertexTLY = float_lerp(coords.vertexTopLeftY, coords.vertexTopRightY, col_prog); + const auto vertexTRY = float_lerp(coords.vertexTopLeftY, coords.vertexTopRightY, next_col_prog); + const auto vertexBLY = float_lerp(coords.vertexBottomLeftY, coords.vertexBottomRightY, col_prog); + const auto vertexBRY = float_lerp(coords.vertexBottomLeftY, coords.vertexBottomRightY, next_col_prog); - glTexCoord2f(float_lerp(coords.textureTopLeftX, coords.textureTopRightX, col_prog), float_lerp(coords.textureTopLeftY, coords.textureBottomLeftY, row_prog)); // top left - glVertex2f(float_lerp(vertexTLX, vertexTRX, col_prog), float_lerp(vertexTLY, vertexBLY, row_prog)); // top left - glTexCoord2f(float_lerp(coords.textureTopLeftX, coords.textureTopRightX, next_col_prog), float_lerp(coords.textureTopRightY, coords.textureBottomRightY, row_prog)); // top right - glVertex2f(float_lerp(vertexTLX, vertexTRX, next_col_prog), float_lerp(vertexTRY, vertexBRY, row_prog)); // top right - glTexCoord2f(float_lerp(coords.textureBottomLeftX, coords.textureBottomRightX, next_col_prog), float_lerp(coords.textureTopRightY, coords.textureBottomRightY, next_row_prog)); // bottom right - glVertex2f(float_lerp(vertexBLX, vertexBRX, next_col_prog), float_lerp(vertexTRY, vertexBRY, next_row_prog)); // bottom right - glTexCoord2f(float_lerp(coords.textureBottomLeftX, coords.textureBottomRightX, col_prog), float_lerp(coords.textureTopLeftY, coords.textureBottomLeftY, next_row_prog)); // bottom left - glVertex2f(float_lerp(vertexBLX, vertexBRX, col_prog), float_lerp(vertexTLY, vertexBLY, next_row_prog)); // bottom left - } - } - } + glTexCoord2f(float_lerp(coords.textureTopLeftX, coords.textureTopRightX, col_prog), + float_lerp(coords.textureTopLeftY, coords.textureBottomLeftY, row_prog)); // top left + glVertex2f(float_lerp(vertexTLX, vertexTRX, col_prog), float_lerp(vertexTLY, vertexBLY, row_prog)); // top left + glTexCoord2f(float_lerp(coords.textureTopLeftX, coords.textureTopRightX, next_col_prog), + float_lerp(coords.textureTopRightY, coords.textureBottomRightY, row_prog)); // top right + glVertex2f(float_lerp(vertexTLX, vertexTRX, next_col_prog), float_lerp(vertexTRY, vertexBRY, row_prog)); // top right + glTexCoord2f(float_lerp(coords.textureBottomLeftX, coords.textureBottomRightX, next_col_prog), + float_lerp(coords.textureTopRightY, coords.textureBottomRightY, next_row_prog)); // bottom right + glVertex2f(float_lerp(vertexBLX, vertexBRX, next_col_prog), float_lerp(vertexTRY, vertexBRY, next_row_prog)); // bottom right + glTexCoord2f(float_lerp(coords.textureBottomLeftX, coords.textureBottomRightX, col_prog), + float_lerp(coords.textureTopLeftY, coords.textureBottomLeftY, next_row_prog)); // bottom left + glVertex2f(float_lerp(vertexBLX, vertexBRX, col_prog), float_lerp(vertexTLY, vertexBLY, next_row_prog)); // bottom left + }//for + }//for + } - glEnd(); + glEnd(); - glBindTexture(GL_TEXTURE_2D, 0); // unbind texture + glBindTexture(GL_TEXTURE_2D, 0); // unbind texture - // prepare gizmos - if ((*gizmos) != nullptr - && nests.isEmpty() - && ((*gizmos) == first_gizmo_effect - || (*gizmos) == selected_effect)) { - (*gizmos)->gizmo_draw(timecode, coords); // set correct gizmo coords - (*gizmos)->gizmo_world_to_screen(); // convert gizmo coords to screen coords - } + // prepare gizmos + if ((*gizmos) != nullptr + && nests.isEmpty() + && ((*gizmos) == first_gizmo_effect + || (*gizmos) == selected_effect)) { + (*gizmos)->gizmo_draw(timecode, coords); // set correct gizmo coords + (*gizmos)->gizmo_world_to_screen(); // convert gizmo coords to screen coords + } - if (!nests.isEmpty()) { - ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); - } + if (!nests.isEmpty()) { + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); + } - glPopMatrix(); + glPopMatrix(); - /*GLfloat motion_blur_frac = (GLfloat) motion_blur_prog / (GLfloat) motion_blur_lim; - if (motion_blur_prog == 0) { - glAccum(GL_LOAD, motion_blur_frac); - } else { - glAccum(GL_ACCUM, motion_blur_frac); - } - motion_blur_prog++;*/ - } - } else { - if (render_audio || (config.enable_audio_scrubbing && audio_scrub && seq->playhead > c->timeline_in)) { - 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, rendering, playback_speed); - nests.removeLast(); - } else { - if (c->lock.tryLock()) { - // clip is not caching, start caching audio - cache_clip(c, playhead, c->audio_reset, !render_audio, nests, playback_speed); - c->lock.unlock(); - } - } - } + /*GLfloat motion_blur_frac = (GLfloat) motion_blur_prog / (GLfloat) motion_blur_lim; + if (motion_blur_prog == 0) { + glAccum(GL_LOAD, motion_blur_frac); + } else { + glAccum(GL_ACCUM, motion_blur_frac); + } + motion_blur_prog++;*/ + } + } else { + if (render_audio || (config.enable_audio_scrubbing && audio_scrub && seq->playhead > c->timeline_in)) { + 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, rendering, playback_speed); + nests.removeLast(); + } else { + if (c->lock.tryLock()) { + // clip is not caching, start caching audio + cache_clip(c, playhead, c->audio_reset, !render_audio, nests, playback_speed); + c->lock.unlock(); + } + } + } - // visually update all the keyframe values - if (c->sequence == seq) { // only if you can currently see them - double ts = (playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition())/s->frame_rate; - for (int i=0;ieffects.size();i++) { - Effect* e = c->effects.at(i); - for (int j=0;jrow_count();j++) { - EffectRow* r = e->row(j); - for (int k=0;kfieldCount();k++) { - r->field(k)->validate_keyframe_data(ts); - } - } - } - } - } - } - } + // visually update all the keyframe values + if (c->sequence == seq) { // only if you can currently see them + double ts = (playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition())/s->frame_rate; + for (int i=0;ieffects.size();i++) { + Effect* e = c->effects.at(i); + for (int j=0;jrow_count();j++) { + EffectRow* r = e->row(j); + for (int k=0;kfieldCount();k++) { + r->field(k)->validate_keyframe_data(ts); + } + } + } + } + } + } + } - if (audio_track_count == 0 && viewer != nullptr) { - viewer->play_wake(); - } + if (audio_track_count == 0 && viewer != nullptr) { + viewer->play_wake(); + } - if (video) { - glPopMatrix(); - } + if (video) { + glPopMatrix(); + } - if (!nests.isEmpty() && nests.last()->fbo != nullptr) { - // returns nested clip's texture - return nests.last()->fbo[0]->texture(); - } + if (!nests.isEmpty() && nests.last()->fbo != nullptr) { + // returns nested clip's texture + return nests.last()->fbo[0]->texture(); + } - return 0; + return 0; } void compose_audio(Viewer* viewer, Sequence* seq, bool render_audio, int playback_speed) { - QVector nests; - bool texture_failed; - compose_sequence(viewer, nullptr, seq, nests, false, render_audio, nullptr, texture_failed, audio_rendering, playback_speed); + QVector nests; + bool texture_failed; + compose_sequence(viewer, nullptr, seq, nests, false, render_audio, nullptr, texture_failed, audio_rendering, playback_speed); } From 23a43aba3e45a71a95950c318ab164f5f8dd4a2f Mon Sep 17 00:00:00 2001 From: Jonathan Noble Date: Sat, 16 Feb 2019 22:27:28 +0000 Subject: [PATCH 3/3] Removed 5 duplicated blocks of code. https://sonarcloud.io/project/issues?id=jonno85uk_olive&issues=AWjXpEv0EzgCzR11xzeI&open=AWjXpEv0EzgCzR11xzeI (cherry picked from commit 64bb2e7cdfac36a69e380a3c0ad5c25b97b4402f) # Conflicts: # app/debug.cpp --- debug.cpp | 115 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/debug.cpp b/debug.cpp index 70b605938..58e6f04ec 100644 --- a/debug.cpp +++ b/debug.cpp @@ -34,63 +34,76 @@ QFile debug_file; QTextStream debug_stream; void open_debug_file() { - QDir debug_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); - debug_dir.mkpath("."); - if (debug_dir.exists()) { - debug_file.setFileName(debug_dir.path() + "/debug_log"); - if (debug_file.open(QFile::WriteOnly)) { - debug_stream.setDevice(&debug_file); - } else { - qWarning() << "Couldn't open debug log file, debug log will not be saved"; - } - } + QDir debug_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); + debug_dir.mkpath("."); + if (debug_dir.exists()) { + debug_file.setFileName(debug_dir.path() + "/debug_log"); + if (debug_file.open(QFile::WriteOnly)) { + debug_stream.setDevice(&debug_file); + } else { + qWarning() << "Couldn't open debug log file, debug log will not be saved"; + } + } } -void close_debug_file() { - if (debug_file.isOpen()) debug_file.close(); +void close_debug_file() +{ + if (debug_file.isOpen()) { + debug_file.close(); + } } -void debug_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { - debug_mutex.lock(); - QByteArray localMsg = msg.toLocal8Bit(); - switch (type) { - case QtDebugMsg: - fprintf(stderr, "[DEBUG] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); - if (debug_file.isOpen()) debug_stream << QString("[DEBUG] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); - debug_info.append(QString("[DEBUG] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); - fflush(stderr); - break; - case QtInfoMsg: - fprintf(stderr, "[INFO] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); - if (debug_file.isOpen()) debug_stream << QString("[INFO] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); - debug_info.append(QString("[INFO] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); - fflush(stderr); - break; - case QtWarningMsg: - fprintf(stderr, "[WARNING] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); - if (debug_file.isOpen()) debug_stream << QString("[WARNING] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); - debug_info.append(QString("[WARNING] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); - fflush(stderr); - break; - case QtCriticalMsg: - fprintf(stderr, "[ERROR] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); - if (debug_file.isOpen()) debug_stream << QString("[ERROR] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); - debug_info.append(QString("[ERROR] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); - fflush(stderr); - break; - case QtFatalMsg: - fprintf(stderr, "[FATAL] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); - if (debug_file.isOpen()) debug_stream << QString("[FATAL] %1 (%2:%3, %4)\n").arg(localMsg.constData(), context.file, QString::number(context.line), context.function); - debug_info.append(QString("[FATAL] %1 (%2:%3, %4)
").arg(localMsg.constData(), context.file, QString::number(context.line), context.function)); - fflush(stderr); -// abort(); - } +void debug_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + debug_mutex.lock(); + const QByteArray localMsg = msg.toLocal8Bit(); + const QDateTime now = QDateTime::currentDateTime(); + const QByteArray timeRepr(now.toString(Qt::ISODate).toLocal8Bit()); + QString msgTag; + QString fontColor; + switch (type) { + case QtDebugMsg: + msgTag = "DEBUG"; + fontColor = "grey"; + break; + case QtInfoMsg: + msgTag = "INFO"; + fontColor = "blue"; + break; + case QtWarningMsg: + msgTag = "WARNING"; + fontColor = "yellow"; + break; + case QtCriticalMsg: + msgTag = "ERROR"; + fontColor = "red"; + break; + case QtFatalMsg: + msgTag = "FATAL"; + fontColor = "red"; + break; + default: + fprintf(stderr, "Unknown debug msg type"); + fflush(stderr); + break; + }//switch + + fprintf(stderr, "%s [%s] %s (%s:%u, %s)\n", timeRepr.data(), msgTag.toLocal8Bit().constData(), localMsg.data(), + context.file, context.line, context.function); + if (debug_file.isOpen()) { + debug_stream << QString("[%1] %2 (%3:%4, %5)\n") + .arg(msgTag, localMsg, context.file, QString::number(context.line), context.function); + } + debug_info.prepend(QString("[%2] %3 (%4:%5, %6)
") + .arg(fontColor, msgTag, localMsg, context.file, QString::number(context.line), context.function)); + fflush(stderr); if (Olive::DebugDialog != nullptr && Olive::DebugDialog->isVisible()) { QMetaObject::invokeMethod(Olive::DebugDialog, "update_log", Qt::QueuedConnection); - } - debug_mutex.unlock(); + } + debug_mutex.unlock(); } -const QString &get_debug_str() { - return debug_info; +const QString &get_debug_str() +{ + return debug_info; }