opengltexture: align all data to 16
Fixes crash if frame is not aligned to 16. This should probably be folded into the Frame class itself at some point.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QtMath>
|
||||
|
||||
#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<double>(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<height_;i++) {
|
||||
memcpy(f.data() + (i*dst_linesize),
|
||||
reinterpret_cast<const char*>(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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user