diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 2d872acfd..7a5e6a6b3 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -303,8 +303,8 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode, const int &divid // Create frame to return FramePtr copy = Frame::Create(); - copy->set_video_params(VideoRenderingParams(vs->width() / divider, - vs->height() / divider, + copy->set_video_params(VideoRenderingParams(GetScaledDimension(vs->width(), divider), + GetScaledDimension(vs->height(), divider), native_pix_fmt_)); copy->set_timestamp(Timecode::timestamp_to_time(target_ts, time_base_)); copy->set_sample_aspect_ratio(aspect_ratio_); @@ -649,6 +649,11 @@ QString FFmpegDecoder::GetIndexFilename() .append(QString::number(stream()->index())); } +int FFmpegDecoder::GetScaledDimension(int dim, int divider) +{ + return dim / divider; +} + void FFmpegDecoder::UnconditionalAudioIndex(const QAtomicInt* cancelled) { // Iterate through each audio frame and extract the PCM data @@ -1082,8 +1087,8 @@ void FFmpegDecoder::InitScaler(int divider) scale_ctx_ = sws_getContext(vs->width(), vs->height(), src_pix_fmt_, - vs->width() / divider, - vs->height() / divider, + GetScaledDimension(vs->width(), divider), + GetScaledDimension(vs->height(), divider), ideal_pix_fmt_, SWS_FAST_BILINEAR, nullptr, diff --git a/app/codec/ffmpeg/ffmpegdecoder.h b/app/codec/ffmpeg/ffmpegdecoder.h index 37558d59e..b5a14678c 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.h +++ b/app/codec/ffmpeg/ffmpegdecoder.h @@ -175,6 +175,8 @@ private: void InitScaler(int divider); void FreeScaler(); + static int GetScaledDimension(int dim, int divider); + SwsContext* scale_ctx_; int scale_divider_; AVPixelFormat src_pix_fmt_; diff --git a/app/render/backend/opengl/opengltexture.cpp b/app/render/backend/opengl/opengltexture.cpp index 67d50822c..f41b7cf6f 100644 --- a/app/render/backend/opengl/opengltexture.cpp +++ b/app/render/backend/opengl/opengltexture.cpp @@ -22,6 +22,7 @@ #include #include +#include #include "openglrenderfunctions.h" #include "render/pixelformat.h" @@ -123,15 +124,51 @@ void OpenGLTexture::Upload(const void *data) Bind(); - created_ctx_->functions()->glTexSubImage2D(GL_TEXTURE_2D, - 0, - 0, - 0, - width_, - height_, - OpenGLRenderFunctions::GetPixelFormat(format_), - OpenGLRenderFunctions::GetPixelType(format_), - data); + if (width_ % 16 != 0) { + // Align to a multiple of 16 + + // FIXME: We should probably fold linesizes into the Frame class proper for optimization + + int new_width = qCeil(static_cast(width_) / 16.0) * 16; + + Frame f; + f.set_video_params(VideoRenderingParams(new_width, height_, format_)); + f.allocate(); + + int src_linesize = PixelFormat::GetBufferSize(format_, width_, 1); + int dst_linesize = PixelFormat::GetBufferSize(format_, new_width, 1); + + for (int i=0;i(data) + i*src_linesize, + src_linesize); + } + + created_ctx_->functions()->glPixelStorei(GL_UNPACK_ROW_LENGTH, new_width); + + created_ctx_->functions()->glTexSubImage2D(GL_TEXTURE_2D, + 0, + 0, + 0, + width_, + height_, + OpenGLRenderFunctions::GetPixelFormat(format_), + OpenGLRenderFunctions::GetPixelType(format_), + f.data()); + + created_ctx_->functions()->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + + } else { + created_ctx_->functions()->glTexSubImage2D(GL_TEXTURE_2D, + 0, + 0, + 0, + width_, + height_, + OpenGLRenderFunctions::GetPixelFormat(format_), + OpenGLRenderFunctions::GetPixelType(format_), + data); + } Release(); }