From e0ec60396592780110e5ca1ab930a0eaa9a7ff29 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Wed, 9 Jan 2019 00:56:49 -0600 Subject: [PATCH] Fixing Scale Mode (None) in previews (#182) * Handle SCALE_NONE mode when optimized for previews (previews are often smaller than the project size) * Fixing 2 memory leaks (thanks PeterM) --- src/FFmpegReader.cpp | 1 + src/FFmpegWriter.cpp | 2 +- src/Timeline.cpp | 61 +++++++++++++++++++++++++++----------------- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 243d7385..dc79be8f 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -1973,6 +1973,7 @@ void FFmpegReader::RemoveAVFrame(AVFrame* remove_frame) { // Free memory av_freep(&remove_frame->data[0]); + AV_FREE_FRAME(&remove_frame); } } diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index bd5486b9..e02c8803 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -1383,7 +1383,7 @@ void FFmpegWriter::write_audio_packets(bool final) } else { // Create a new array - final_samples = new int16_t[audio_input_position * (av_get_bytes_per_sample(audio_codec->sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))]; + final_samples = (int16_t*)av_malloc(sizeof(int16_t) * audio_input_position * (av_get_bytes_per_sample(audio_codec->sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))); // Copy audio into buffer for frame memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec->sample_fmt)); diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 6d1b0cde..d97b13e4 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -387,35 +387,48 @@ void Timeline::add_layer(std::shared_ptr new_frame, Clip* source_clip, in QSize source_size = source_image->size(); switch (source_clip->scale) { - case (SCALE_FIT): - // keep aspect ratio - source_size.scale(max_width, max_height, Qt::KeepAspectRatio); + case (SCALE_FIT): { + // keep aspect ratio + source_size.scale(max_width, max_height, Qt::KeepAspectRatio); - // Debug output - ZmqLogger::Instance()->AppendDebugMethod("Timeline::add_layer (Scale: SCALE_FIT)", "source_frame->number", source_frame->number, "source_width", source_size.width(), "source_height", source_size.height(), "", -1, "", -1, "", -1); - break; + // Debug output + ZmqLogger::Instance()->AppendDebugMethod("Timeline::add_layer (Scale: SCALE_FIT)", "source_frame->number", source_frame->number, "source_width", source_size.width(), "source_height", source_size.height(), "", -1, "", -1, "", -1); + break; + } + case (SCALE_STRETCH): { + // ignore aspect ratio + source_size.scale(max_width, max_height, Qt::IgnoreAspectRatio); - case (SCALE_STRETCH): - // ignore aspect ratio - source_size.scale(max_width, max_height, Qt::IgnoreAspectRatio); + // Debug output + ZmqLogger::Instance()->AppendDebugMethod("Timeline::add_layer (Scale: SCALE_STRETCH)", "source_frame->number", source_frame->number, "source_width", source_size.width(), "source_height", source_size.height(), "", -1, "", -1, "", -1); + break; + } + case (SCALE_CROP): { + QSize width_size(max_width, round(max_width / (float(source_size.width()) / float(source_size.height())))); + QSize height_size(round(max_height / (float(source_size.height()) / float(source_size.width()))), max_height); - // Debug output - ZmqLogger::Instance()->AppendDebugMethod("Timeline::add_layer (Scale: SCALE_STRETCH)", "source_frame->number", source_frame->number, "source_width", source_size.width(), "source_height", source_size.height(), "", -1, "", -1, "", -1); - break; + // respect aspect ratio + if (width_size.width() >= max_width && width_size.height() >= max_height) + source_size.scale(width_size.width(), width_size.height(), Qt::KeepAspectRatio); + else + source_size.scale(height_size.width(), height_size.height(), Qt::KeepAspectRatio); - case (SCALE_CROP): - QSize width_size(max_width, round(max_width / (float(source_size.width()) / float(source_size.height())))); - QSize height_size(round(max_height / (float(source_size.height()) / float(source_size.width()))), max_height); + // Debug output + ZmqLogger::Instance()->AppendDebugMethod("Timeline::add_layer (Scale: SCALE_CROP)", "source_frame->number", source_frame->number, "source_width", source_size.width(), "source_height", source_size.height(), "", -1, "", -1, "", -1); + break; + } + case (SCALE_NONE): { + // Calculate ratio of source size to project size + // Even with no scaling, previews need to be adjusted correctly + // (otherwise NONE scaling draws the frame image outside of the preview) + float source_width_ratio = source_size.width() / float(info.width); + float source_height_ratio = source_size.height() / float(info.height); + source_size.scale(max_width * source_width_ratio, max_height * source_height_ratio, Qt::KeepAspectRatio); - // respect aspect ratio - if (width_size.width() >= max_width && width_size.height() >= max_height) - source_size.scale(width_size.width(), width_size.height(), Qt::KeepAspectRatio); - else - source_size.scale(height_size.width(), height_size.height(), Qt::KeepAspectRatio); - - // Debug output - ZmqLogger::Instance()->AppendDebugMethod("Timeline::add_layer (Scale: SCALE_CROP)", "source_frame->number", source_frame->number, "source_width", source_size.width(), "source_height", source_size.height(), "", -1, "", -1, "", -1); - break; + // Debug output + ZmqLogger::Instance()->AppendDebugMethod("Timeline::add_layer (Scale: SCALE_NONE)", "source_frame->number", source_frame->number, "source_width", source_size.width(), "source_height", source_size.height(), "", -1, "", -1, "", -1); + break; + } } /* GRAVITY LOCATION - Initialize X & Y to the correct values (before applying location curves) */