From e3403a5a5352acfa89bb32e3617e21428b8f1d3f Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 26 Jul 2022 09:40:26 -0700 Subject: [PATCH] render: create less textures --- app/codec/ffmpeg/ffmpegdecoder.cpp | 33 +++++++++-- app/codec/ffmpeg/ffmpegdecoder.h | 4 ++ app/render/opengl/openglrenderer.cpp | 80 +++++++++----------------- app/render/opengl/openglrenderer.h | 19 +++---- app/render/renderer.cpp | 84 +++++++++++++++++++--------- app/render/renderer.h | 39 +++++++++---- app/render/texture.cpp | 2 +- app/render/texture.h | 20 +------ app/render/videoparams.h | 2 + 9 files changed, 156 insertions(+), 127 deletions(-) diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index c2dbe2488..9f66a9e3e 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -61,6 +61,9 @@ FFmpegDecoder::FFmpegDecoder() : input_fmt_(AV_PIX_FMT_NONE), native_internal_pix_fmt_(VideoParams::kFormatInvalid), native_output_pix_fmt_(VideoParams::kFormatInvalid), + y_tex_(nullptr), + u_tex_(nullptr), + v_tex_(nullptr), working_frame_(nullptr), working_packet_(nullptr), cache_at_zero_(false), @@ -216,7 +219,12 @@ TexturePtr FFmpegDecoder::RetrieveVideoInternal(Renderer *renderer, const ration plane_params.set_channel_count(1); plane_params.set_divider(1); plane_params.set_format(native_internal_pix_fmt_); - TexturePtr y_plane = renderer->CreateTexture(plane_params, f->data[0], f->linesize[0] / px_size); + + if (!y_tex_) { + y_tex_ = renderer->CreateTexture(plane_params, f->data[0], f->linesize[0] / px_size); + } else { + y_tex_->Upload(f->data[0], f->linesize[0] / px_size); + } if (src_fmt == AV_PIX_FMT_YUV420P || src_fmt == AV_PIX_FMT_YUV422P @@ -236,13 +244,22 @@ TexturePtr FFmpegDecoder::RetrieveVideoInternal(Renderer *renderer, const ration plane_params.set_height(plane_params.height()/2); } - TexturePtr u_plane = renderer->CreateTexture(plane_params, f->data[1], f->linesize[1] / px_size); - TexturePtr v_plane = renderer->CreateTexture(plane_params, f->data[2], f->linesize[2] / px_size); + if (!u_tex_) { + u_tex_ = renderer->CreateTexture(plane_params, f->data[1], f->linesize[1] / px_size); + } else { + u_tex_->Upload(f->data[1], f->linesize[1] / px_size); + } + + if (!v_tex_) { + v_tex_ = renderer->CreateTexture(plane_params, f->data[2], f->linesize[2] / px_size); + } else { + v_tex_->Upload(f->data[2], f->linesize[2] / px_size); + } ShaderJob job; - job.Insert(QStringLiteral("y_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(y_plane))); - job.Insert(QStringLiteral("u_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(u_plane))); - job.Insert(QStringLiteral("v_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(v_plane))); + job.Insert(QStringLiteral("y_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(y_tex_))); + job.Insert(QStringLiteral("u_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(u_tex_))); + job.Insert(QStringLiteral("v_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(v_tex_))); job.Insert(QStringLiteral("bits_per_pixel"), NodeValue(NodeValue::kInt, bits_per_pixel)); job.Insert(QStringLiteral("jpeg_range"), NodeValue(NodeValue::kBoolean, jpeg_range)); @@ -296,6 +313,10 @@ void FFmpegDecoder::CloseInternal() input_fmt_ = AV_PIX_FMT_NONE; native_internal_pix_fmt_ = VideoParams::kFormatInvalid; native_output_pix_fmt_ = VideoParams::kFormatInvalid; + + y_tex_ = nullptr; + u_tex_ = nullptr; + v_tex_ = nullptr; } QString FFmpegDecoder::id() const diff --git a/app/codec/ffmpeg/ffmpegdecoder.h b/app/codec/ffmpeg/ffmpegdecoder.h index 1c0d25bb8..837d5e04c 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.h +++ b/app/codec/ffmpeg/ffmpegdecoder.h @@ -165,6 +165,10 @@ private: VideoParams::Format native_output_pix_fmt_; int native_channel_count_; + TexturePtr y_tex_; + TexturePtr u_tex_; + TexturePtr v_tex_; + AVFrame *working_frame_; AVPacket *working_packet_; diff --git a/app/render/opengl/openglrenderer.cpp b/app/render/opengl/openglrenderer.cpp index 5078b963c..a06c44ffd 100644 --- a/app/render/opengl/openglrenderer.cpp +++ b/app/render/opengl/openglrenderer.cpp @@ -107,7 +107,7 @@ void OpenGLRenderer::Init(QOpenGLContext *existing_ctx) bool OpenGLRenderer::Init() { - QMutexLocker locker(&global_opengl_mutex); + GL_PREAMBLE; if (context_) { qCritical() << "Can't initialize already initialized OpenGLRenderer"; @@ -187,16 +187,11 @@ void OpenGLRenderer::ClearDestination(Texture *texture, double r, double g, doub } } -QVariant OpenGLRenderer::CreateNativeTexture2D(int width, int height, VideoParams::Format format, int channel_count, const void *data, int linesize) +QVariant OpenGLRenderer::CreateNativeTexture(int width, int height, int depth, VideoParams::Format format, int channel_count, const void *data, int linesize) { GL_PREAMBLE; - return CreateNativeTexture2DInternal(width, height, format, channel_count, data, linesize); -} - -QVariant OpenGLRenderer::CreateNativeTexture3D(int width, int height, int depth, VideoParams::Format format, int channel_count, const void *data, int linesize) -{ - GL_PREAMBLE; + bool is_3d = depth > 1; // Generate new texture GLuint texture; @@ -205,18 +200,27 @@ QVariant OpenGLRenderer::CreateNativeTexture3D(int width, int height, int depth, functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize); + GLenum target_current = is_3d ? GL_TEXTURE_BINDING_3D : GL_TEXTURE_BINDING_2D; + GLenum target = is_3d ? GL_TEXTURE_3D : GL_TEXTURE_2D; + GLint current_tex; - functions_->glGetIntegerv(GL_TEXTURE_BINDING_3D, ¤t_tex); + functions_->glGetIntegerv(target_current, ¤t_tex); - functions_->glBindTexture(GL_TEXTURE_3D, texture); + functions_->glBindTexture(target, texture); - context_->extraFunctions()->glTexImage3D(GL_TEXTURE_3D, 0, GetInternalFormat(format, channel_count), - width, height, depth, 0, GetPixelFormat(channel_count), - GetPixelType(format), data); + if (is_3d) { + context_->extraFunctions()->glTexImage3D(target, 0, GetInternalFormat(format, channel_count), + width, height, depth, 0, GetPixelFormat(channel_count), + GetPixelType(format), data); + } else { + functions_->glTexImage2D(target, 0, GetInternalFormat(format, channel_count), + width, height, 0, GetPixelFormat(channel_count), + GetPixelType(format), data); + } functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - functions_->glBindTexture(GL_TEXTURE_3D, current_tex); + functions_->glBindTexture(target, current_tex); return texture; } @@ -294,8 +298,10 @@ void OpenGLRenderer::UploadToTexture(Texture *texture, const void *data, int lin GLuint t = texture->id().value(); const VideoParams& p = texture->params(); - GLenum tex_type = texture->type() == Texture::k2D ? GL_TEXTURE_2D : GL_TEXTURE_3D; - GLenum tex_binding = texture->type() == Texture::k2D ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_3D; + bool is_3d = texture->params().is_3d(); + + GLenum tex_type = !is_3d ? GL_TEXTURE_2D : GL_TEXTURE_3D; + GLenum tex_binding = !is_3d ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_3D; // Store currently bound texture so it can be restored later GLint current_tex; @@ -308,7 +314,7 @@ void OpenGLRenderer::UploadToTexture(Texture *texture, const void *data, int lin { PRINT_GL_ERRORS; - if (texture->type() == Texture::k2D) { + if (!is_3d) { functions_->glTexSubImage2D(tex_type, 0, 0, 0, p.effective_width(), p.effective_height(), GetPixelFormat(p.channel_count()), GetPixelType(p.format()), @@ -502,7 +508,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video functions_->glActiveTexture(GL_TEXTURE0 + i); - GLenum target = (texture && texture->type() == Texture::k3D) ? GL_TEXTURE_3D : GL_TEXTURE_2D; + GLenum target = (texture && texture->params().is_3d()) ? GL_TEXTURE_3D : GL_TEXTURE_2D; functions_->glBindTexture(target, tex_id); if (tex_id) { @@ -584,11 +590,11 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video TexturePtr output_tex, input_tex; if (real_iteration_count > 1) { // Create one texture to bounce off - output_tex = CreateTextureFromNativeHandle(CreateNativeTexture2DInternal(destination_params), destination_params); + output_tex = CreateTexture(destination_params); if (real_iteration_count > 2) { // Create a second texture bounce off - input_tex = CreateTextureFromNativeHandle(CreateNativeTexture2DInternal(destination_params), destination_params); + input_tex = CreateTexture(destination_params); } } @@ -648,7 +654,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video // Release any textures we bound before for (int i=textures_to_bind.size()-1; i>=0; i--) { TexturePtr texture = textures_to_bind.at(i).texture; - GLenum target = (texture && texture->type() == Texture::k3D) ? GL_TEXTURE_3D : GL_TEXTURE_2D; + GLenum target = (texture && texture->params().is_3d()) ? GL_TEXTURE_3D : GL_TEXTURE_2D; functions_->glActiveTexture(GL_TEXTURE0 + i); functions_->glBindTexture(target, 0); } @@ -788,38 +794,6 @@ void OpenGLRenderer::ClearDestinationInternal(double r, double g, double b, doub functions_->glClear(GL_COLOR_BUFFER_BIT); } -QVariant OpenGLRenderer::CreateNativeTexture2DInternal(int width, int height, VideoParams::Format format, int channel_count, const void *data, int linesize) -{ - GLuint texture; - functions_->glGenTextures(1, &texture); - texture_params_.insert(texture, {width, height, 1, format, channel_count}); - - functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize); - - GLint current_tex; - functions_->glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_tex); - - functions_->glBindTexture(GL_TEXTURE_2D, texture); - - { - PRINT_GL_ERRORS; - functions_->glTexImage2D(GL_TEXTURE_2D, 0, GetInternalFormat(format, channel_count), - width, height, 0, GetPixelFormat(channel_count), - GetPixelType(format), data); - } - - functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - - functions_->glBindTexture(GL_TEXTURE_2D, current_tex); - - return texture; -} - -QVariant OpenGLRenderer::CreateNativeTexture2DInternal(const VideoParams ¶ms, const void *data, int linesize) -{ - return CreateNativeTexture2DInternal(params.effective_width(), params.effective_height(), params.format(), params.channel_count(), data, linesize); -} - GLuint OpenGLRenderer::CompileShader(GLenum type, const QString &code) { static const QString shader_preamble = diff --git a/app/render/opengl/openglrenderer.h b/app/render/opengl/openglrenderer.h index 2e51480b1..1377e475c 100644 --- a/app/render/opengl/openglrenderer.h +++ b/app/render/opengl/openglrenderer.h @@ -47,18 +47,10 @@ public: virtual void PostDestroy() override; -public slots: virtual void PostInit() override; - virtual void DestroyInternal() override; - virtual void ClearDestination(olive::Texture *texture = nullptr, double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) override; - virtual QVariant CreateNativeTexture2D(int width, int height, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override; - virtual QVariant CreateNativeTexture3D(int width, int height, int depth, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override; - - virtual void DestroyNativeTexture(QVariant texture) override; - virtual QVariant CreateNativeShader(olive::ShaderCode code) override; virtual void DestroyNativeShader(QVariant shader) override; @@ -71,13 +63,19 @@ public slots: virtual Color GetPixelFromTexture(olive::Texture *texture, const QPointF &pt) override; -protected slots: +protected: virtual void Blit(QVariant shader, olive::ShaderJob job, olive::Texture* destination, olive::VideoParams destination_params, bool clear_destination) override; + virtual QVariant CreateNativeTexture(int width, int height, int depth, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override; + + virtual void DestroyNativeTexture(QVariant texture) override; + + virtual void DestroyInternal() override; + private: static GLint GetInternalFormat(VideoParams::Format format, int channel_layout); @@ -93,9 +91,6 @@ private: void ClearDestinationInternal(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0); - QVariant CreateNativeTexture2DInternal(int width, int height, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0); - QVariant CreateNativeTexture2DInternal(const VideoParams ¶ms, const void* data = nullptr, int linesize = 0); - GLuint CompileShader(GLenum type, const QString &code); QOpenGLContext* context_; diff --git a/app/render/renderer.cpp b/app/render/renderer.cpp index e174a4b35..39a0aaff0 100644 --- a/app/render/renderer.cpp +++ b/app/render/renderer.cpp @@ -20,36 +20,54 @@ #include "renderer.h" +#include +#include #include -#include "common/ocioutils.h" - namespace olive { Renderer::Renderer(QObject *parent) : QObject(parent) { - -} - -TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, Texture::Type type, const void *data, int linesize) -{ - QVariant v; - - if (type == Texture::k3D) { - v = CreateNativeTexture3D(params.effective_width(), params.effective_height(), - params.effective_depth(), params.format(), params.channel_count(), data, linesize); - } else { - v = CreateNativeTexture2D(params.effective_width(), params.effective_height(), params.format(), - params.channel_count(), data, linesize); - } - - return CreateTextureFromNativeHandle(v, params, type); + QTimer *texture_garbage_collector = new QTimer(this); + texture_garbage_collector->setInterval(MAX_TEXTURE_LIFE); + connect(texture_garbage_collector, &QTimer::timeout, this, &Renderer::ClearOldTextures); + texture_garbage_collector->start(); } TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, const void *data, int linesize) { - return CreateTexture(params, Texture::k2D, data, linesize); + QVariant v; + + /*for (auto it=texture_cache_.begin(); it!=texture_cache_.end(); it++) { + if (it->width == params.effective_width() + && it->height == params.effective_height() + && it->depth == params.effective_depth() + && it->format == params.format() + && it->channel_count == params.channel_count()) { + this->Flush(); + v = it->handle; + texture_cache_.erase(it); + break; + } + }*/ + + v = CreateNativeTexture(params.effective_width(), params.effective_height(), params.effective_depth(), + params.format(), params.channel_count(), data, linesize); + + return CreateTextureFromNativeHandle(v, params); +} + +void Renderer::DestroyTexture(Texture *texture) +{ + /*texture_cache_.push_back({texture->params().effective_width(), + texture->params().effective_height(), + texture->params().effective_depth(), + texture->params().format(), + texture->params().channel_count(), + texture->id(), + QDateTime::currentMSecsSinceEpoch()});*/ + DestroyNativeTexture(texture->id()); } TexturePtr Renderer::InterlaceTexture(TexturePtr top, TexturePtr bottom, const VideoParams ¶ms) @@ -83,6 +101,11 @@ QVariant Renderer::GetDefaultShader() void Renderer::Destroy() { + for (auto it=texture_cache_.begin(); it!=texture_cache_.end(); it++) { + DestroyNativeTexture(it->handle); + } + texture_cache_.clear(); + if (!default_shader_.isNull()) { DestroyNativeShader(default_shader_); default_shader_.clear(); @@ -98,13 +121,13 @@ void Renderer::Destroy() DestroyInternal(); } -TexturePtr Renderer::CreateTextureFromNativeHandle(const QVariant &v, const VideoParams ¶ms, Texture::Type type) +TexturePtr Renderer::CreateTextureFromNativeHandle(const QVariant &v, const VideoParams ¶ms) { if (v.isNull()) { return nullptr; } - return std::make_shared(this, v, params, type); + return std::make_shared(this, v, params); } bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::ColorContext *ctx) @@ -175,8 +198,7 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::Col } // Allocate 3D LUT - color_ctx.lut3d_textures[i].texture = CreateTexture(VideoParams(edge_len, edge_len, edge_len, VideoParams::kFormatFloat32, VideoParams::kRGBChannelCount), - Texture::k3D, values); + color_ctx.lut3d_textures[i].texture = CreateTexture(VideoParams(edge_len, edge_len, edge_len, VideoParams::kFormatFloat32, VideoParams::kRGBChannelCount), values); color_ctx.lut3d_textures[i].name = sampler_name; color_ctx.lut3d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear; } @@ -206,9 +228,7 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::Col } // Allocate 1D LUT - color_ctx.lut1d_textures[i].texture = CreateTexture(VideoParams(width, height, VideoParams::kFormatFloat32, (channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? 1 : VideoParams::kRGBChannelCount), - Texture::k2D, - values); + color_ctx.lut1d_textures[i].texture = CreateTexture(VideoParams(width, height, VideoParams::kFormatFloat32, (channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? 1 : VideoParams::kRGBChannelCount), values); color_ctx.lut1d_textures[i].name = sampler_name; color_ctx.lut1d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear; } @@ -219,6 +239,18 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::Col } } +void Renderer::ClearOldTextures() +{ + for (auto it=texture_cache_.begin(); it!=texture_cache_.end(); ) { + if (it->accessed < QDateTime::currentMSecsSinceEpoch() - MAX_TEXTURE_LIFE) { + DestroyNativeTexture(it->handle); + it = texture_cache_.erase(it); + } else { + it++; + } + } +} + void Renderer::BlitColorManaged(const ColorTransformJob &color_job, Texture *destination, const VideoParams ¶ms) { ColorContext color_ctx; diff --git a/app/render/renderer.h b/app/render/renderer.h index 839be32cf..dc1fb19a0 100644 --- a/app/render/renderer.h +++ b/app/render/renderer.h @@ -45,9 +45,10 @@ public: virtual bool Init() = 0; - TexturePtr CreateTexture(const VideoParams& params, Texture::Type type, const void* data = nullptr, int linesize = 0); TexturePtr CreateTexture(const VideoParams& params, const void *data = nullptr, int linesize = 0); + void DestroyTexture(Texture *texture); + void BlitToTexture(QVariant shader, olive::ShaderJob job, olive::Texture* destination, @@ -82,18 +83,10 @@ public: virtual void PostDestroy() = 0; -public slots: virtual void PostInit() = 0; - virtual void DestroyInternal() = 0; - virtual void ClearDestination(olive::Texture *texture = nullptr, double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) = 0; - virtual QVariant CreateNativeTexture2D(int width, int height, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) = 0; - virtual QVariant CreateNativeTexture3D(int width, int height, int depth, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) = 0; - - virtual void DestroyNativeTexture(QVariant texture) = 0; - virtual QVariant CreateNativeShader(olive::ShaderCode code) = 0; virtual void DestroyNativeShader(QVariant shader) = 0; @@ -106,15 +99,18 @@ public slots: virtual Color GetPixelFromTexture(olive::Texture *texture, const QPointF &pt) = 0; -protected slots: +protected: virtual void Blit(QVariant shader, olive::ShaderJob job, olive::Texture* destination, olive::VideoParams destination_params, bool clear_destination) = 0; -protected: - TexturePtr CreateTextureFromNativeHandle(const QVariant &v, const VideoParams ¶ms, Texture::Type type = Texture::k2D); + virtual QVariant CreateNativeTexture(int width, int height, int depth, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) = 0; + + virtual void DestroyNativeTexture(QVariant texture) = 0; + + virtual void DestroyInternal() = 0; private: struct ColorContext { @@ -130,16 +126,35 @@ private: }; + TexturePtr CreateTextureFromNativeHandle(const QVariant &v, const VideoParams ¶ms); + bool GetColorContext(const ColorTransformJob &color_job, ColorContext* ctx); QHash color_cache_; + struct CachedTexture + { + int width; + int height; + int depth; + VideoParams::Format format; + int channel_count; + QVariant handle; + qint64 accessed; + }; + + const int MAX_TEXTURE_LIFE = 10000; + std::list texture_cache_; + QMutex color_cache_mutex_; QVariant default_shader_; QVariant interlace_texture_; +private slots: + void ClearOldTextures(); + }; } diff --git a/app/render/texture.cpp b/app/render/texture.cpp index 33973ddaf..f3b5fb9d0 100644 --- a/app/render/texture.cpp +++ b/app/render/texture.cpp @@ -29,7 +29,7 @@ const Texture::Interpolation Texture::kDefaultInterpolation = Texture::kMipmappe Texture::~Texture() { if (renderer_) { - renderer_->DestroyNativeTexture(id_); + renderer_->DestroyTexture(this); } } diff --git a/app/render/texture.h b/app/render/texture.h index 612b3e2f2..6179878a8 100644 --- a/app/render/texture.h +++ b/app/render/texture.h @@ -32,11 +32,6 @@ class Renderer; class Texture { public: - enum Type { - k2D, - k3D - }; - enum Interpolation { kNearest, kLinear, @@ -50,19 +45,17 @@ public: */ Texture(const VideoParams& param) : renderer_(nullptr), - params_(param), - type_(k2D) + params_(param) { } /** * @brief Construct a real texture linked to a renderer backend */ - Texture(Renderer* renderer, const QVariant& native, const VideoParams& param, Type type) : + Texture(Renderer* renderer, const QVariant& native, const VideoParams& param) : renderer_(renderer), params_(param), - id_(native), - type_(type) + id_(native) { } @@ -117,11 +110,6 @@ public: return params_.pixel_aspect_ratio(); } - Type type() const - { - return type_; - } - Renderer* renderer() const { return renderer_; @@ -134,8 +122,6 @@ private: QVariant id_; - Type type_; - }; using TexturePtr = std::shared_ptr; diff --git a/app/render/videoparams.h b/app/render/videoparams.h index f3cedd28b..28d8c29fe 100644 --- a/app/render/videoparams.h +++ b/app/render/videoparams.h @@ -121,6 +121,8 @@ public: calculate_effective_size(); } + bool is_3d() const { return depth_ > 1; } + const rational& time_base() const { return time_base_;