From e658f741d63294355cc080346b3b9d566eb68d51 Mon Sep 17 00:00:00 2001 From: Chris Kirmse Date: Mon, 12 Oct 2020 17:56:53 -0700 Subject: [PATCH] fix crashes with video widths not multiple of 4 - need to align 32 everywhere for sws_scale to not crash --- include/FFmpegUtilities.h | 12 ++++++------ include/Frame.h | 2 +- src/FFmpegReader.cpp | 4 ++-- src/Frame.cpp | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/FFmpegUtilities.h b/include/FFmpegUtilities.h index c637f9445..f9f07d51c 100644 --- a/include/FFmpegUtilities.h +++ b/include/FFmpegUtilities.h @@ -159,7 +159,7 @@ #define AV_SET_FILENAME(oc, f) oc->AV_FILENAME = av_strdup(f) #define MY_INPUT_BUFFER_PADDING_SIZE AV_INPUT_BUFFER_PADDING_SIZE #define AV_ALLOCATE_FRAME() av_frame_alloc() - #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1) + #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, av_cpu_max_align()) #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame) #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame) #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet) @@ -175,8 +175,8 @@ #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) (AVPixelFormat) av_stream->codecpar->format #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format - #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, 1) - #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 1) + #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, av_cpu_max_align()) + #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, av_cpu_max_align()) #define AV_OUTPUT_CONTEXT(output_context, path) avformat_alloc_output_context2( output_context, NULL, NULL, path) #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0) #define AV_OPTION_SET( av_stream, priv_data, name, value, avcodec) av_opt_set(priv_data, name, value, 0); avcodec_parameters_from_context(av_stream->codecpar, avcodec); @@ -194,7 +194,7 @@ #define AV_SET_FILENAME(oc, f) snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", f) #define MY_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE #define AV_ALLOCATE_FRAME() av_frame_alloc() - #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1) + #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 32) #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame) #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame) #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet) @@ -210,8 +210,8 @@ #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) (AVPixelFormat) av_stream->codecpar->format #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format - #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, 1) - #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 1) + #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, 32) + #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 32) #define AV_OUTPUT_CONTEXT(output_context, path) avformat_alloc_output_context2( output_context, NULL, NULL, path) #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0) #define AV_OPTION_SET( av_stream, priv_data, name, value, avcodec) av_opt_set(priv_data, name, value, 0); avcodec_parameters_from_context(av_stream->codecpar, avcodec); diff --git a/include/Frame.h b/include/Frame.h index f4ff54d44..0b926b60f 100644 --- a/include/Frame.h +++ b/include/Frame.h @@ -156,7 +156,7 @@ namespace openshot void AddColor(int new_width, int new_height, std::string new_color); /// Add (or replace) pixel data to the frame - void AddImage(int new_width, int new_height, int bytes_per_pixel, QImage::Format type, const unsigned char *pixels_); + void AddImage(int new_width, int new_height, int bytes_per_pixel, int bytes_per_line, QImage::Format type, const unsigned char *pixels_); /// Add (or replace) pixel data to the frame void AddImage(std::shared_ptr new_image); diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 694e75f10..60ebc19c3 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -1161,7 +1161,7 @@ bool FFmpegReader::GetAVFrame() { // Use only the first frame like avcodec_decode_video2 if (frameFinished == 0 ) { frameFinished = 1; - av_image_alloc(pFrame->data, pFrame->linesize, info.width, info.height, (AVPixelFormat)(pStream->codecpar->format), 1); + av_image_alloc(pFrame->data, pFrame->linesize, info.width, info.height, (AVPixelFormat)(pStream->codecpar->format), 32); av_image_copy(pFrame->data, pFrame->linesize, (const uint8_t**)next_frame->data, next_frame->linesize, (AVPixelFormat)(pStream->codecpar->format), info.width, info.height); } @@ -1372,7 +1372,7 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame) { std::shared_ptr f = CreateFrame(current_frame); // Add Image data to frame - f->AddImage(width, height, 4, QImage::Format_RGBA8888, buffer); + f->AddImage(width, height, 4, pFrameRGB->linesize[0], QImage::Format_RGBA8888, buffer); // Update working cache working_cache.Add(f); diff --git a/src/Frame.cpp b/src/Frame.cpp index 483df7688..3fcb0ef78 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -759,11 +759,11 @@ void Frame::AddColor(int new_width, int new_height, std::string new_color) } // Add (or replace) pixel data to the frame -void Frame::AddImage(int new_width, int new_height, int bytes_per_pixel, QImage::Format type, const unsigned char *pixels_) +void Frame::AddImage(int new_width, int new_height, int bytes_per_pixel, int bytes_per_line, QImage::Format type, const unsigned char *pixels_) { // Create new buffer const GenericScopedLock lock(addingImageSection); - int buffer_size = new_width * new_height * bytes_per_pixel; + int buffer_size = bytes_per_line * new_height; qbuffer = new unsigned char[buffer_size](); // Copy buffer data @@ -772,7 +772,7 @@ void Frame::AddImage(int new_width, int new_height, int bytes_per_pixel, QImage: // Create new image object, and fill with pixel data #pragma omp critical (AddImage) { - image = std::shared_ptr(new QImage(qbuffer, new_width, new_height, new_width * bytes_per_pixel, type, (QImageCleanupFunction) &openshot::Frame::cleanUpBuffer, (void*) qbuffer)); + image = std::shared_ptr(new QImage(qbuffer, new_width, new_height, bytes_per_line, type, (QImageCleanupFunction) &openshot::Frame::cleanUpBuffer, (void*) qbuffer)); // Always convert to RGBA8888 (if different) if (image->format() != QImage::Format_RGBA8888)