From 2b1640ac04ebb543728fe8d0582e4ef294d48a01 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 4 May 2020 01:08:46 +1000 Subject: [PATCH] frame/texture: use dividers when allocating buffers Allows render pipeline to know the "real" and "simulated" resolution of a divided buffer. --- app/codec/decoder.cpp | 2 +- app/codec/decoder.h | 2 +- app/codec/ffmpeg/ffmpegdecoder.cpp | 16 ++++--- app/codec/ffmpeg/ffmpegdecoder.h | 2 +- app/codec/frame.cpp | 6 +-- app/codec/oiio/oiiodecoder.cpp | 2 +- app/codec/oiio/oiiodecoder.h | 2 +- app/render/backend/opengl/openglproxy.cpp | 28 +++++------ app/render/backend/opengl/opengltexture.cpp | 46 +++++++++---------- app/render/backend/opengl/opengltexture.h | 14 +++--- .../backend/opengl/opengltexturecache.cpp | 10 ++-- .../backend/opengl/opengltexturecache.h | 4 +- app/render/backend/opengl/openglworker.cpp | 4 +- app/widget/scope/waveform/waveform.cpp | 2 +- app/widget/viewer/viewerdisplay.cpp | 4 +- 15 files changed, 74 insertions(+), 70 deletions(-) diff --git a/app/codec/decoder.cpp b/app/codec/decoder.cpp index 2cccc4b1c..b224e5f99 100644 --- a/app/codec/decoder.cpp +++ b/app/codec/decoder.cpp @@ -57,7 +57,7 @@ void Decoder::set_stream(StreamPtr fs) stream_ = fs; } -FramePtr Decoder::RetrieveVideo(const rational &/*timecode*/, const int &/*divider*/) +FramePtr Decoder::RetrieveVideo(const rational &/*timecode*/, const int &/*divider*/, bool /*use_proxies*/) { return nullptr; } diff --git a/app/codec/decoder.h b/app/codec/decoder.h index 1f9179e96..d6adbe0c4 100644 --- a/app/codec/decoder.h +++ b/app/codec/decoder.h @@ -138,7 +138,7 @@ public: * A FramePtr of valid data at this timecode or nullptr if there was nothing to retrieve at the provided timecode or * the media could not be opened. */ - virtual FramePtr RetrieveVideo(const rational& timecode, const int& divider); + virtual FramePtr RetrieveVideo(const rational& timecode, const int& divider, bool use_proxies); /** * @brief Retrieve video frame diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 17925d5c0..3c497adb5 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -135,7 +135,7 @@ bool FFmpegDecoder::Open() return true; } -FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode, const int ÷r) +FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode, const int ÷r, bool use_proxies) { QMutexLocker locker(&mutex_); @@ -169,9 +169,10 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode, const int &divid if (in) { FramePtr copy = Frame::Create(); - copy->set_video_params(VideoRenderingParams(GetScaledDimension(vs->width(), vs->using_proxy()), - GetScaledDimension(vs->height(), vs->using_proxy()), - native_pix_fmt_)); + copy->set_video_params(VideoRenderingParams(vs->width(), + vs->height(), + native_pix_fmt_, + vs->using_proxy())); copy->set_timestamp(Timecode::timestamp_to_time(target_ts, time_base_)); copy->set_sample_aspect_ratio(aspect_ratio_); copy->allocate(); @@ -314,9 +315,10 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode, const int &divid // Create frame to return FramePtr copy = Frame::Create(); - copy->set_video_params(VideoRenderingParams(GetScaledDimension(vs->width(), divider), - GetScaledDimension(vs->height(), divider), - native_pix_fmt_)); + copy->set_video_params(VideoRenderingParams(vs->width(), + vs->height(), + native_pix_fmt_, + divider)); copy->set_timestamp(Timecode::timestamp_to_time(target_ts, time_base_)); copy->set_sample_aspect_ratio(aspect_ratio_); copy->allocate(); diff --git a/app/codec/ffmpeg/ffmpegdecoder.h b/app/codec/ffmpeg/ffmpegdecoder.h index f02e37f75..206b0ab5a 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.h +++ b/app/codec/ffmpeg/ffmpegdecoder.h @@ -134,7 +134,7 @@ public: virtual bool Probe(Footage *f, const QAtomicInt *cancelled) override; virtual bool Open() override; - virtual FramePtr RetrieveVideo(const rational &timecode, const int& divider) override; + virtual FramePtr RetrieveVideo(const rational &timecode, const int& divider, bool use_proxies) override; virtual SampleBufferPtr RetrieveAudio(const rational &timecode, const rational &length, const AudioRenderingParams& params) override; virtual void Close() override; diff --git a/app/codec/frame.cpp b/app/codec/frame.cpp index bb18ace05..ec026d0df 100644 --- a/app/codec/frame.cpp +++ b/app/codec/frame.cpp @@ -47,7 +47,7 @@ void Frame::set_video_params(const VideoRenderingParams ¶ms) params_ = params; // Align linesize to 16 - linesize_ = qCeil(static_cast(params.width()) / 16.0) * 16; + linesize_ = qCeil(static_cast(width()) / 16.0) * 16; } int Frame::linesize_pixels() const @@ -62,12 +62,12 @@ int Frame::linesize_bytes() const const int &Frame::width() const { - return params_.width(); + return params_.effective_width(); } const int &Frame::height() const { - return params_.height(); + return params_.effective_height(); } const PixelFormat::Format &Frame::format() const diff --git a/app/codec/oiio/oiiodecoder.cpp b/app/codec/oiio/oiiodecoder.cpp index 5a2eac463..27e02991f 100644 --- a/app/codec/oiio/oiiodecoder.cpp +++ b/app/codec/oiio/oiiodecoder.cpp @@ -154,7 +154,7 @@ bool OIIODecoder::Open() return true; } -FramePtr OIIODecoder::RetrieveVideo(const rational &timecode, const int& divider) +FramePtr OIIODecoder::RetrieveVideo(const rational &timecode, const int& divider, bool /*use_proxies*/) { QMutexLocker locker(&mutex_); diff --git a/app/codec/oiio/oiiodecoder.h b/app/codec/oiio/oiiodecoder.h index 2bc03d169..0412789a8 100644 --- a/app/codec/oiio/oiiodecoder.h +++ b/app/codec/oiio/oiiodecoder.h @@ -40,7 +40,7 @@ public: virtual bool Probe(Footage *f, const QAtomicInt* cancelled) override; virtual bool Open() override; - virtual FramePtr RetrieveVideo(const rational &timecode, const int& divider) override; + virtual FramePtr RetrieveVideo(const rational &timecode, const int& divider, bool use_proxies) override; virtual void Close() override; virtual bool SupportsVideo() override; diff --git a/app/render/backend/opengl/openglproxy.cpp b/app/render/backend/opengl/openglproxy.cpp index 194ac6dc4..05b4e5609 100644 --- a/app/render/backend/opengl/openglproxy.cpp +++ b/app/render/backend/opengl/openglproxy.cpp @@ -130,19 +130,19 @@ void OpenGLProxy::FrameToValue(FramePtr frame, StreamPtr stream, NodeValueTable* } } - VideoRenderingParams footage_params(frame->width(), frame->height(), frame->format()); - - footage_tex_ref = texture_cache_.Get(ctx_, footage_params, frame); + footage_tex_ref = texture_cache_.Get(ctx_, frame); if (ocio_method == ColorManager::kOCIOFast) { if (!color_processor->IsEnabled()) { color_processor->Enable(ctx_, video_stream->premultiplied_alpha()); } + VideoRenderingParams frame_params = frame->video_params(); + // Check frame aspect ratio if (frame->sample_aspect_ratio() != 1 && frame->sample_aspect_ratio() != 0) { - int new_width = frame->width(); - int new_height = frame->height(); + int new_width = frame_params.width(); + int new_height = frame_params.height(); // Scale the frame in a way that does not reduce the resolution if (frame->sample_aspect_ratio() > 1) { @@ -153,14 +153,16 @@ void OpenGLProxy::FrameToValue(FramePtr frame, StreamPtr stream, NodeValueTable* new_height = qRound(static_cast(new_height) / frame->sample_aspect_ratio().toDouble()); } - footage_params = VideoRenderingParams(new_width, - new_height, - footage_params.format()); + frame_params = VideoRenderingParams(new_width, + new_height, + frame_params.format(), + frame_params.divider()); } - VideoRenderingParams dest_params(footage_params.width(), - footage_params.height(), - video_params_.format()); + VideoRenderingParams dest_params(frame_params.width(), + frame_params.height(), + video_params_.format(), + frame_params.divider()); // Create destination texture OpenGLTextureCache::ReferencePtr associated_tex_ref = texture_cache_.Get(ctx_, dest_params); @@ -329,8 +331,8 @@ void OpenGLProxy::RunNodeAccelerated(const Node *node, const TimeRange &range, N int res_param_location = shader->uniformLocation(QStringLiteral("%1_resolution").arg(input->id())); if (res_param_location > -1) { shader->setUniformValue(res_param_location, - static_cast(texture->texture()->width() * video_params_.divider()), - static_cast(texture->texture()->height() * video_params_.divider())); + static_cast(texture->texture()->width() * texture->texture()->divider()), + static_cast(texture->texture()->height() * texture->texture()->divider())); } } diff --git a/app/render/backend/opengl/opengltexture.cpp b/app/render/backend/opengl/opengltexture.cpp index d5013c10f..021840fcb 100644 --- a/app/render/backend/opengl/opengltexture.cpp +++ b/app/render/backend/opengl/opengltexture.cpp @@ -31,10 +31,7 @@ OLIVE_NAMESPACE_ENTER OpenGLTexture::OpenGLTexture() : created_ctx_(nullptr), - texture_(0), - width_(0), - height_(0), - format_(PixelFormat::PIX_FMT_INVALID) + texture_(0) { } @@ -48,7 +45,7 @@ bool OpenGLTexture::IsCreated() const return (texture_); } -void OpenGLTexture::Create(QOpenGLContext *ctx, int width, int height, const PixelFormat::Format &format, const void* data, int linesize) +void OpenGLTexture::Create(QOpenGLContext *ctx, const VideoRenderingParams ¶ms, const void* data, int linesize) { if (!ctx) { qWarning() << "OpenGLTexture::Create was passed an invalid context"; @@ -58,9 +55,7 @@ void OpenGLTexture::Create(QOpenGLContext *ctx, int width, int height, const Pix Destroy(); created_ctx_ = ctx; - width_ = width; - height_ = height; - format_ = format; + params_ = params; connect(created_ctx_, SIGNAL(aboutToBeDestroyed()), this, SLOT(Destroy()), Qt::DirectConnection); @@ -68,9 +63,9 @@ void OpenGLTexture::Create(QOpenGLContext *ctx, int width, int height, const Pix CreateInternal(created_ctx_, &texture_, data, linesize); } -void OpenGLTexture::Create(QOpenGLContext *ctx, int width, int height, const PixelFormat::Format &format) +void OpenGLTexture::Create(QOpenGLContext *ctx, const VideoRenderingParams ¶ms) { - Create(ctx, width, height, format, nullptr, 0); + Create(ctx, params, nullptr, 0); } void OpenGLTexture::Create(QOpenGLContext *ctx, FramePtr frame) @@ -80,7 +75,7 @@ void OpenGLTexture::Create(QOpenGLContext *ctx, FramePtr frame) void OpenGLTexture::Create(QOpenGLContext *ctx, Frame *frame) { - Create(ctx, frame->width(), frame->height(), frame->format(), frame->data(), frame->linesize_pixels()); + Create(ctx, frame->video_params(), frame->data(), frame->linesize_pixels()); } void OpenGLTexture::Destroy() @@ -107,17 +102,17 @@ void OpenGLTexture::Release() const int &OpenGLTexture::width() const { - return width_; + return params_.effective_width(); } const int &OpenGLTexture::height() const { - return height_; + return params_.effective_height(); } const PixelFormat::Format &OpenGLTexture::format() const { - return format_; + return params_.format(); } const GLuint &OpenGLTexture::texture() const @@ -125,6 +120,11 @@ const GLuint &OpenGLTexture::texture() const return texture_; } +const int &OpenGLTexture::divider() const +{ + return params_.divider(); +} + void OpenGLTexture::Upload(FramePtr frame) { Upload(frame.get()); @@ -150,10 +150,10 @@ void OpenGLTexture::Upload(const void *data, int linesize) 0, 0, 0, - width_, - height_, - OpenGLRenderFunctions::GetPixelFormat(format_), - OpenGLRenderFunctions::GetPixelType(format_), + width(), + height(), + OpenGLRenderFunctions::GetPixelFormat(format()), + OpenGLRenderFunctions::GetPixelType(format()), data); created_ctx_->functions()->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); @@ -183,12 +183,12 @@ void OpenGLTexture::CreateInternal(QOpenGLContext* create_ctx, GLuint* tex, cons // Allocate storage for texture f->glTexImage2D(GL_TEXTURE_2D, 0, - OpenGLRenderFunctions::GetInternalFormat(format_), - width_, - height_, + OpenGLRenderFunctions::GetInternalFormat(format()), + width(), + height(), 0, - OpenGLRenderFunctions::GetPixelFormat(format_), - OpenGLRenderFunctions::GetPixelType(format_), + OpenGLRenderFunctions::GetPixelFormat(format()), + OpenGLRenderFunctions::GetPixelType(format()), data); // Return linesize to default diff --git a/app/render/backend/opengl/opengltexture.h b/app/render/backend/opengl/opengltexture.h index 70fa653f7..ef213526e 100644 --- a/app/render/backend/opengl/opengltexture.h +++ b/app/render/backend/opengl/opengltexture.h @@ -1,4 +1,4 @@ -/*** +/*** Olive - Non-Linear Video Editor Copyright (C) 2019 Olive Team @@ -41,8 +41,8 @@ public: DISABLE_COPY_MOVE(OpenGLTexture) - void Create(QOpenGLContext* ctx, int width, int height, const PixelFormat::Format &format, const void *data, int linesize); - void Create(QOpenGLContext* ctx, int width, int height, const PixelFormat::Format &format); + void Create(QOpenGLContext* ctx, const VideoRenderingParams& params, const void *data, int linesize); + void Create(QOpenGLContext* ctx, const VideoRenderingParams& params); void Create(QOpenGLContext* ctx, FramePtr frame); void Create(QOpenGLContext* ctx, Frame* frame); @@ -60,6 +60,8 @@ public: const GLuint& texture() const; + const int& divider() const; + void Upload(FramePtr frame); void Upload(Frame* frame); void Upload(const void *data, int linesize); @@ -74,11 +76,7 @@ private: GLuint texture_; - int width_; - - int height_; - - PixelFormat::Format format_; + VideoRenderingParams params_; }; diff --git a/app/render/backend/opengl/opengltexturecache.cpp b/app/render/backend/opengl/opengltexturecache.cpp index a54994467..5ca1fee23 100644 --- a/app/render/backend/opengl/opengltexturecache.cpp +++ b/app/render/backend/opengl/opengltexturecache.cpp @@ -29,14 +29,14 @@ OpenGLTextureCache::~OpenGLTextureCache() } } -OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext *ctx, const VideoRenderingParams ¶ms, FramePtr frame) +OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext *ctx, FramePtr frame) { - return Get(ctx, params, frame.get()); + return Get(ctx, frame.get()); } -OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext *ctx, const VideoRenderingParams ¶ms, Frame *frame) +OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext *ctx, Frame *frame) { - return Get(ctx, params, frame->data(), frame->linesize_pixels()); + return Get(ctx, frame->video_params(), frame->data(), frame->linesize_pixels()); } OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext* ctx, const VideoRenderingParams ¶ms, const void *data, int linesize) @@ -61,7 +61,7 @@ OpenGLTextureCache::ReferencePtr OpenGLTextureCache::Get(QOpenGLContext* ctx, co // If we didn't find a texture, we'll need to create one if (!texture) { texture = std::make_shared(); - texture->Create(ctx, params.effective_width(), params.effective_height(), params.format()); + texture->Create(ctx, params); } ReferencePtr ref = std::make_shared(this, texture); diff --git a/app/render/backend/opengl/opengltexturecache.h b/app/render/backend/opengl/opengltexturecache.h index 2baa87a67..42c08dbb3 100644 --- a/app/render/backend/opengl/opengltexturecache.h +++ b/app/render/backend/opengl/opengltexturecache.h @@ -57,8 +57,8 @@ public: DISABLE_COPY_MOVE(OpenGLTextureCache) - ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params, FramePtr frame); - ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params, Frame* frame); + ReferencePtr Get(QOpenGLContext *ctx, FramePtr frame); + ReferencePtr Get(QOpenGLContext *ctx, Frame* frame); ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params, const void *data, int linesize); ReferencePtr Get(QOpenGLContext *ctx, const VideoRenderingParams& params); diff --git a/app/render/backend/opengl/openglworker.cpp b/app/render/backend/opengl/openglworker.cpp index 67f3fa835..aa31b9e32 100644 --- a/app/render/backend/opengl/openglworker.cpp +++ b/app/render/backend/opengl/openglworker.cpp @@ -38,7 +38,9 @@ OpenGLWorker::OpenGLWorker(VideoRenderFrameCache *frame_cache, QObject *parent) void OpenGLWorker::FrameToValue(DecoderPtr decoder, StreamPtr stream, const TimeRange &range, NodeValueTable *table) { - FramePtr frame = decoder->RetrieveVideo(range.in(), video_params().divider()); + FramePtr frame = decoder->RetrieveVideo(range.in(), + video_params().divider(), + video_params().mode() == RenderMode::kOffline); if (frame) { emit RequestFrameToValue(frame, stream, table); diff --git a/app/widget/scope/waveform/waveform.cpp b/app/widget/scope/waveform/waveform.cpp index 211e66ef3..5f9225b3f 100644 --- a/app/widget/scope/waveform/waveform.cpp +++ b/app/widget/scope/waveform/waveform.cpp @@ -196,7 +196,7 @@ void WaveformScope::UploadTextureFromBuffer() managed_tex_.Destroy(); texture_.Create(context(), buffer_); - managed_tex_.Create(context(), buffer_->width(), buffer_->height(), buffer_->format()); + managed_tex_.Create(context(), buffer_->video_params()); } else { texture_.Upload(buffer_); } diff --git a/app/widget/viewer/viewerdisplay.cpp b/app/widget/viewer/viewerdisplay.cpp index 779f65237..469fcd7aa 100644 --- a/app/widget/viewer/viewerdisplay.cpp +++ b/app/widget/viewer/viewerdisplay.cpp @@ -83,7 +83,7 @@ void ViewerDisplayWidget::SetImage(const QString &fn) load_buffer_.set_video_params(VideoRenderingParams(input->spec().width, input->spec().height, image_format)); load_buffer_.allocate(); - texture_.Create(context(), input->spec().width, input->spec().height, image_format); + texture_.Create(context(), VideoRenderingParams(input->spec().width, input->spec().height, image_format)); } input->read_image(input->spec().format, load_buffer_.data(), OIIO::AutoStride, load_buffer_.linesize_bytes()); @@ -132,7 +132,7 @@ void ViewerDisplayWidget::SetImageFromLoadBuffer(Frame *in_buffer) || texture_.width() != in_buffer->width() || texture_.height() != in_buffer->height() || texture_.format() != in_buffer->format()) { - texture_.Create(context(), in_buffer->width(), in_buffer->height(), in_buffer->format(), in_buffer->data(), load_buffer_.linesize_pixels()); + texture_.Create(context(), in_buffer->video_params(), in_buffer->data(), load_buffer_.linesize_pixels()); } else { texture_.Upload(in_buffer); }