From 3c1ac3eeba95d573925e5af8b0534db58f16e0a5 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 11 Nov 2020 21:53:24 +1100 Subject: [PATCH] upgraded to ocio v2 --- CMakeLists.txt | 2 +- app/codec/ffmpeg/ffmpegdecoder.cpp | 57 +++--- app/codec/ffmpeg/ffmpegdecoder.h | 2 +- app/codec/frame.cpp | 12 +- app/codec/frame.h | 2 +- app/common/CMakeLists.txt | 1 + app/common/ocioutils.h | 27 +++ app/config/config.cpp | 2 - .../videostreamproperties.cpp | 3 +- .../projectproperties/projectproperties.cpp | 3 +- app/render/audioplaybackcache.cpp | 2 +- app/render/backend/opengl/openglrenderer.cpp | 166 +++++++----------- app/render/backend/opengl/openglrenderer.h | 6 - app/render/backend/renderer.cpp | 101 ++++------- app/render/backend/renderer.h | 4 +- app/render/color.cpp | 94 +++++----- app/render/color.h | 56 +++--- app/render/colormanager.cpp | 12 +- app/render/colormanager.h | 11 +- app/render/colorprocessor.cpp | 55 ++++-- app/render/colorprocessor.h | 5 +- app/render/colortransform.h | 3 +- app/render/pixelformat.cpp | 22 +++ app/render/pixelformat.h | 3 + app/render/previewautocacher.cpp | 8 +- app/render/rendermanager.cpp | 7 +- app/render/rendermanager.h | 4 +- app/render/renderprocessor.cpp | 10 +- app/render/shaderinfo.h | 14 ++ app/task/export/export.cpp | 5 - app/task/project/loadotio/loadotio.cpp | 2 +- app/threading/threadpool.cpp | 8 +- app/widget/colorwheel/colorgradientwidget.cpp | 4 +- app/widget/colorwheel/colorgradientwidget.h | 2 +- app/widget/colorwheel/colorwheelwidget.cpp | 4 +- app/widget/manageddisplay/manageddisplay.h | 5 + app/widget/scope/histogram/histogram.cpp | 2 +- app/widget/scope/waveform/waveform.cpp | 4 +- app/widget/viewer/viewer.cpp | 1 + app/widget/viewer/viewerdisplay.cpp | 9 +- 40 files changed, 378 insertions(+), 362 deletions(-) create mode 100644 app/common/ocioutils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b1f3471a..337ca5784 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ endif() find_package(OpenGL REQUIRED) -find_package(OpenColorIO REQUIRED) +find_package(OpenColorIO 2.0.0 REQUIRED) find_package(OpenImageIO 1.6 REQUIRED) diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 9b3ae55cd..ac4e402b7 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -51,7 +51,7 @@ OLIVE_NAMESPACE_ENTER FFmpegDecoder::FFmpegDecoder() : scale_ctx_(nullptr), scale_divider_(0), - pool_(QThread::idealThreadCount()), + pool_(QThread::idealThreadCount()*2), is_working_(false), cache_at_zero_(false), cache_at_eof_(false) @@ -120,21 +120,20 @@ FramePtr FFmpegDecoder::RetrieveStillImage(const rational &timecode, const int & if (ret >= 0) { // Create frame to return - FramePtr copy = Frame::Create(); - copy->set_video_params(VideoParams(frame->width, - frame->height, - native_pix_fmt_, - std::static_pointer_cast(stream())->pixel_aspect_ratio(), - std::static_pointer_cast(stream())->interlacing(), - divider)); - copy->set_timestamp(timecode); - copy->allocate(); + output_frame = Frame::Create(); + output_frame->set_video_params(VideoParams(frame->width, + frame->height, + native_pix_fmt_, + std::static_pointer_cast(stream())->pixel_aspect_ratio(), + std::static_pointer_cast(stream())->interlacing(), + divider)); + output_frame->set_timestamp(timecode); + output_frame->allocate(); - uint8_t* copy_data = reinterpret_cast(copy->data()); - int copy_linesize = copy->linesize_bytes(); - FFmpegFrameToNativeBuffer(frame->data, frame->linesize, ©_data, ©_linesize); + uint8_t* copy_data = reinterpret_cast(output_frame->data()); + int copy_linesize = output_frame->linesize_bytes(); - return copy; + FFmpegBufferToNativeBuffer(frame->data, frame->linesize, ©_data, ©_linesize); } else { qWarning() << "Failed to retrieve still image from decoder"; } @@ -151,6 +150,11 @@ FramePtr FFmpegDecoder::RetrieveVideoInternal(const rational &timecode, const in { VideoStreamPtr vs = std::static_pointer_cast(stream()); + if (scale_divider_ != divider) { + FreeScaler(); + InitScaler(divider); + } + if (vs->video_type() == VideoStream::kVideoTypeStill || vs->video_type() == VideoStream::kVideoTypeImageSequence) { @@ -158,8 +162,6 @@ FramePtr FFmpegDecoder::RetrieveVideoInternal(const rational &timecode, const in } else { - FFmpegFramePool::ElementPtr return_frame = nullptr; - int64_t target_ts = vs->get_time_in_timebase_units(timecode); int divided_width = VideoParams::GetScaledDimension(vs->width(), divider); @@ -171,12 +173,10 @@ FramePtr FFmpegDecoder::RetrieveVideoInternal(const rational &timecode, const in // Set new frame pool parameters pool_.SetParameters(divided_width, divided_height, native_pix_fmt_); - } else { - return_frame = GetFrameFromCache(target_ts); } // Retrieve frame - return_frame = RetrieveFrame(target_ts, divider); + FFmpegFramePool::ElementPtr return_frame = RetrieveFrame(target_ts, divider); // We found the frame, we'll return a copy if (return_frame) { @@ -563,7 +563,7 @@ uint64_t FFmpegDecoder::ValidateChannelLayout(AVStream* stream) return av_get_default_channel_layout(stream->codecpar->channels); } -void FFmpegDecoder::FFmpegFrameToNativeBuffer(uint8_t **input_data, int *input_linesize, uint8_t** output_buffer, int* output_linesize) +void FFmpegDecoder::FFmpegBufferToNativeBuffer(uint8_t **input_data, int *input_linesize, uint8_t** output_buffer, int* output_linesize) { sws_scale(scale_ctx_, input_data, @@ -640,17 +640,12 @@ void FFmpegDecoder::ClearFrameCache() FFmpegFramePool::ElementPtr FFmpegDecoder::RetrieveFrame(const int64_t& target_ts, int divider) { - if (scale_divider_ != divider) { - FreeScaler(); - InitScaler(divider); - } - int64_t seek_ts = target_ts; bool still_seeking = false; // If the frame wasn't in the frame cache, see if this frame cache is too old to use if (cached_frames_.isEmpty() - || (target_ts < cached_frames_.first()->timestamp() && target_ts > cached_frames_.last()->timestamp() + 2*second_ts_)) { + || (target_ts < cached_frames_.first()->timestamp() || target_ts > cached_frames_.last()->timestamp() + 2*second_ts_)) { ClearFrameCache(); instance_.Seek(seek_ts); @@ -659,6 +654,12 @@ FFmpegFramePool::ElementPtr FFmpegDecoder::RetrieveFrame(const int64_t& target_t } still_seeking = true; + } else { + // Search cache for frame + FFmpegFramePool::ElementPtr cached_frame = GetFrameFromCache(target_ts); + if (cached_frame) { + return cached_frame; + } } int ret; @@ -727,9 +728,9 @@ FFmpegFramePool::ElementPtr FFmpegDecoder::RetrieveFrame(const int64_t& target_t } // Store in queue, converting to native format - int destination_linesize = Frame::generate_linesize_bytes(VideoParams::GetScaledDimension(instance_.avstream()->codecpar->width, divider), native_pix_fmt_); uint8_t* destination_data = cached->data(); - FFmpegFrameToNativeBuffer(working_frame->data, working_frame->linesize, &destination_data, &destination_linesize); + int destination_linesize = Frame::generate_linesize_bytes(VideoParams::GetScaledDimension(instance_.avstream()->codecpar->width, divider), native_pix_fmt_); + FFmpegBufferToNativeBuffer(working_frame->data, working_frame->linesize, &destination_data, &destination_linesize); // Set timestamp so this frame can be identified later cached->set_timestamp(working_frame->pts); diff --git a/app/codec/ffmpeg/ffmpegdecoder.h b/app/codec/ffmpeg/ffmpegdecoder.h index 4dcb5992b..b74aa5bde 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.h +++ b/app/codec/ffmpeg/ffmpegdecoder.h @@ -130,7 +130,7 @@ private: static uint64_t ValidateChannelLayout(AVStream *stream); - void FFmpegFrameToNativeBuffer(uint8_t** input_data, int* input_linesize, uint8_t **output_buffer, int *output_linesize); + void FFmpegBufferToNativeBuffer(uint8_t** input_data, int* input_linesize, uint8_t **output_buffer, int *output_linesize); FFmpegFramePool::ElementPtr GetFrameFromCache(const int64_t& t) const; diff --git a/app/codec/frame.cpp b/app/codec/frame.cpp index 8b06cfbe6..9abdac922 100644 --- a/app/codec/frame.cpp +++ b/app/codec/frame.cpp @@ -45,14 +45,14 @@ void Frame::set_video_params(const VideoParams ¶ms) { params_ = params; - linesize_ = generate_linesize_bytes(params_.width(), params_.format()); + linesize_ = generate_linesize_bytes(width(), params_.format()); linesize_pixels_ = linesize_ / PixelFormat::BytesPerPixel(params_.format()); } int Frame::generate_linesize_bytes(int width, PixelFormat::Format format) { // Align to 32 bytes (not sure if this is necessary?) - return ((PixelFormat::BytesPerPixel(format) * width) + 31) & ~31; + return PixelFormat::BytesPerPixel(format) * ((width + 31) & ~31); } Color Frame::get_pixel(int x, int y) const @@ -82,15 +82,17 @@ void Frame::set_pixel(int x, int y, const Color &c) c.toData(data_.data() + byte_offset, video_params().format()); } -void Frame::allocate() +bool Frame::allocate() { // Assume this frame is intended to be a video frame if (!params_.is_valid()) { qWarning() << "Tried to allocate a frame with invalid parameters"; - return; + return false; } - data_.resize(PixelFormat::GetBufferSize(params_.format(), linesize_, params_.height())); + data_.resize(PixelFormat::GetBufferSize(params_.format(), linesize_, height())); + + return true; } OLIVE_NAMESPACE_EXIT diff --git a/app/codec/frame.h b/app/codec/frame.h index 57938096d..8c89902b9 100644 --- a/app/codec/frame.h +++ b/app/codec/frame.h @@ -116,7 +116,7 @@ public: * * If a memory buffer has been previously allocated without destroying, this function will destroy it. */ - void allocate(); + bool allocate(); /** * @brief Return whether the frame is allocated or not diff --git a/app/common/CMakeLists.txt b/app/common/CMakeLists.txt index 847d6e426..553af7017 100644 --- a/app/common/CMakeLists.txt +++ b/app/common/CMakeLists.txt @@ -37,6 +37,7 @@ set(OLIVE_SOURCES common/lerp.h common/memorypool.h common/memorypool.cpp + common/ocioutils.h common/qtutils.h common/qtutils.cpp common/range.h diff --git a/app/common/ocioutils.h b/app/common/ocioutils.h new file mode 100644 index 000000000..a290a1e50 --- /dev/null +++ b/app/common/ocioutils.h @@ -0,0 +1,27 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#ifndef OCIOUTILS_H +#define OCIOUTILS_H + +#include +namespace OCIO = OpenColorIO_v2_0dev; + +#endif // OCIOUTILS_H diff --git a/app/config/config.cpp b/app/config/config.cpp index f2db463d7..a40718a8d 100644 --- a/app/config/config.cpp +++ b/app/config/config.cpp @@ -121,8 +121,6 @@ void Config::SetDefaults() // Online/offline settings SetEntryInternal(QStringLiteral("OnlinePixelFormat"), NodeParam::kInt, PixelFormat::PIX_FMT_RGBA32F); SetEntryInternal(QStringLiteral("OfflinePixelFormat"), NodeParam::kInt, PixelFormat::PIX_FMT_RGBA16F); - SetEntryInternal(QStringLiteral("OnlineOCIOMethod"), NodeParam::kInt, ColorManager::kOCIOAccurate); - SetEntryInternal(QStringLiteral("OfflineOCIOMethod"), NodeParam::kInt, ColorManager::kOCIOFast); } void Config::Load() diff --git a/app/dialog/footageproperties/streamproperties/videostreamproperties.cpp b/app/dialog/footageproperties/streamproperties/videostreamproperties.cpp index 0aaca3a43..b9bf9112d 100644 --- a/app/dialog/footageproperties/streamproperties/videostreamproperties.cpp +++ b/app/dialog/footageproperties/streamproperties/videostreamproperties.cpp @@ -25,9 +25,8 @@ #include #include #include -#include -namespace OCIO = OCIO_NAMESPACE::v1; +#include "common/ocioutils.h" #include "core.h" #include "project/item/footage/footage.h" #include "project/project.h" diff --git a/app/dialog/projectproperties/projectproperties.cpp b/app/dialog/projectproperties/projectproperties.cpp index 5a8713f5c..509a47e61 100644 --- a/app/dialog/projectproperties/projectproperties.cpp +++ b/app/dialog/projectproperties/projectproperties.cpp @@ -27,10 +27,9 @@ #include #include #include -#include -namespace OCIO = OCIO_NAMESPACE::v1; #include "common/filefunctions.h" +#include "common/ocioutils.h" #include "config/config.h" #include "core.h" #include "render/colormanager.h" diff --git a/app/render/audioplaybackcache.cpp b/app/render/audioplaybackcache.cpp index 595b76620..a4997c035 100644 --- a/app/render/audioplaybackcache.cpp +++ b/app/render/audioplaybackcache.cpp @@ -157,7 +157,7 @@ void AudioPlaybackCache::WriteSilence(const TimeRange &range, qint64 job_time) void AudioPlaybackCache::ShiftEvent(const rational &from_in_time, const rational &to_in_time) { - if (from_in_time == to_in_time) { + if (from_in_time == to_in_time || GetLength().isNull()) { // Nothing to be done return; } diff --git a/app/render/backend/opengl/openglrenderer.cpp b/app/render/backend/opengl/openglrenderer.cpp index 117ffdeae..a435bfd75 100644 --- a/app/render/backend/opengl/openglrenderer.cpp +++ b/app/render/backend/opengl/openglrenderer.cpp @@ -21,6 +21,7 @@ #include "openglrenderer.h" #include +#include OLIVE_NAMESPACE_ENTER @@ -44,16 +45,6 @@ const QVector blit_texcoords = { 1.0f, 1.0f }; -const QVector flipped_blit_texcoords = { - 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, - - 0.0f, 1.0f, - 0.0f, 0.0f, - 1.0f, 0.0f -}; - OpenGLRenderer::OpenGLRenderer(QObject* parent) : Renderer(parent), context_(nullptr) @@ -110,33 +101,11 @@ void OpenGLRenderer::PostInit() // Set up framebuffer used for various things functions_->glGenFramebuffers(1, &framebuffer_); - - // Set up vertex array object - vao_.create(); - - // Set up vertex buffer - vert_vbo_.create(); - vert_vbo_.bind(); - vert_vbo_.allocate(blit_vertices.constData(), blit_vertices.size() * sizeof(GLfloat)); - vert_vbo_.release(); - - // Set up fragment buffer - frag_vbo_.create(); - frag_vbo_.bind(); - frag_vbo_.allocate(blit_texcoords.constData(), blit_texcoords.size() * sizeof(GLfloat)); - frag_vbo_.release(); } void OpenGLRenderer::Destroy() { if (context_) { - // Delete buffers - vert_vbo_.destroy(); - frag_vbo_.destroy(); - - // Delete vertex array object - vao_.destroy(); - // Delete framebuffer functions_->glDeleteFramebuffers(1, &framebuffer_); @@ -181,12 +150,19 @@ QVariant OpenGLRenderer::CreateNativeTexture(VideoParams p, void *data, int line functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize); + GLint current_tex; + functions_->glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_tex); + + functions_->glBindTexture(GL_TEXTURE_2D, texture); + functions_->glTexImage2D(GL_TEXTURE_2D, 0, GetInternalFormat(p.format()), - p.width(), p.height(), 0, GL_RGBA, + p.effective_width(), p.effective_height(), 0, GL_RGBA, GetPixelType(p.format()), data); functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + functions_->glBindTexture(GL_TEXTURE_2D, current_tex); + return texture; } @@ -215,8 +191,6 @@ QVariant OpenGLRenderer::CreateNativeShader(ShaderCode code) goto error; } - qDebug() << "Shader created successfully"; - return Node::PtrToValue(program); error: @@ -254,13 +228,12 @@ void OpenGLRenderer::UploadToTexture(Texture *texture, void *data, int linesize) void OpenGLRenderer::DownloadFromTexture(Texture* texture, void *data, int linesize) { - GLuint t = texture->id().value(); const VideoParams& p = texture->params(); GLint current_tex; functions_->glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_tex); - functions_->glBindTexture(GL_TEXTURE_2D, t); + AttachTextureAsDestination(texture); functions_->glPixelStorei(GL_PACK_ROW_LENGTH, linesize); @@ -274,6 +247,8 @@ void OpenGLRenderer::DownloadFromTexture(Texture* texture, void *data, int lines functions_->glPixelStorei(GL_PACK_ROW_LENGTH, 0); + DetachTextureAsDestination(); + functions_->glBindTexture(GL_TEXTURE_2D, current_tex); } @@ -315,23 +290,6 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat shader->setUniformValue(variable_location, value.data.toFloat()); break; case NodeInput::kVec2: - /*if (corresponding_input && corresponding_input->IsArray()) { - QVector nv = value.value< QVector >(); - QVector a(nv.size()); - - for (int j=0;j(); - } - - shader->setUniformValueArray(variable_location, a.constData(), a.size()); - - int count_location = shader->uniformLocation(QStringLiteral("%1_count").arg(it.key())); - if (count_location > -1) { - shader->setUniformValue(count_location, a.size()); - } - } else { - - }*/ shader->setUniformValue(variable_location, value.data.value()); break; case NodeInput::kVec3: @@ -349,8 +307,8 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat case NodeInput::kColor: { Color color = value.data.value(); - - shader->setUniformValue(variable_location, color.red(), color.green(), color.blue(), color.alpha()); + shader->setUniformValue(variable_location, + color.red(), color.green(), color.blue(), color.alpha()); break; } case NodeInput::kBoolean: @@ -423,14 +381,6 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat } } - // Set ove_resolution to the destination to the "logical" resolution of the destination - shader->setUniformValue("ove_resolution", - static_cast(destination_params.width()), - static_cast(destination_params.height())); - - // Set the viewport to the "physical" resolution of the destination - functions_->glViewport(0, 0, destination_params.effective_width(), destination_params.effective_height()); - // Bind all textures for (int i=0; iglActiveTexture(GL_TEXTURE0 + i); @@ -438,10 +388,37 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat PrepareInputTexture(job.GetBilinearFiltering()); } + // Set ove_resolution to the destination to the "logical" resolution of the destination + shader->setUniformValue("ove_resolution", + static_cast(destination_params.width()), + static_cast(destination_params.height())); + + // Set matrix to identity + shader->setUniformValue("ove_mvpmat", job.GetMatrix()); + + // Set the viewport to the "physical" resolution of the destination + functions_->glViewport(0, 0, + destination_params.effective_width(), + destination_params.effective_height()); + // Bind vertex array object + QOpenGLVertexArrayObject vao_; + vao_.create(); vao_.bind(); // Set buffers + QOpenGLBuffer vert_vbo_; + vert_vbo_.create(); + vert_vbo_.bind(); + vert_vbo_.allocate(blit_vertices.constData(), blit_vertices.size() * sizeof(GLfloat)); + vert_vbo_.release(); + + QOpenGLBuffer frag_vbo_; + frag_vbo_.create(); + frag_vbo_.bind(); + frag_vbo_.allocate(blit_texcoords.constData(), blit_texcoords.size() * sizeof(GLfloat)); + frag_vbo_.release(); + int vertex_location = shader->attributeLocation("a_position"); vert_vbo_.bind(); functions_->glEnableVertexAttribArray(vertex_location); @@ -493,21 +470,21 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat DetachTextureAsDestination(); } } else { - // Always draw to output_tex + // Always draw to output_tex, which gets swapped with input_tex every iteration AttachTextureAsDestination(output_tex.get()); - - if (iteration > 0) { - // If this is not the first iteration, replace the iterative texture with the one we - // last drew - functions_->glActiveTexture(GL_TEXTURE0 + iterative_input); - functions_->glBindTexture(GL_TEXTURE_2D, input_tex->id().value()); - PrepareInputTexture(job.GetBilinearFiltering()); - } - - // Swap so that the next iteration, the texture we draw now will be the input texture next - std::swap(output_tex, input_tex); } + if (iteration > 0) { + // If this is not the first iteration, replace the iterative texture with the one we + // last drew + functions_->glActiveTexture(GL_TEXTURE0 + iterative_input); + functions_->glBindTexture(GL_TEXTURE_2D, input_tex->id().value()); + PrepareInputTexture(job.GetBilinearFiltering()); + } + + // Swap so that the next iteration, the texture we draw now will be the input texture next + std::swap(output_tex, input_tex); + // Blit this texture through this shader functions_->glDrawArrays(GL_TRIANGLES, 0, blit_vertices.size() / 3); } @@ -526,41 +503,16 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destinat functions_->glBindTexture(GL_TEXTURE_2D, 0); } - // Release vertex array object - vao_.release(); - // Release shader shader->release(); + + // Release vertex array object + frag_vbo_.destroy(); + vert_vbo_.destroy(); + vao_.release(); + vao_.destroy(); } -/*void OpenGLRenderer::Blit(Renderer::Texture *source, QVariant shader, Renderer::ShaderUniformMap parameters, Renderer::Texture *destination) -{ - QOpenGLShaderProgram* program = Node::ValueToPtr(shader); - - if (!program) { - qCritical() << "Attempted to blit with a null shader"; - return; - } - - if (destination) { - AttachTextureAsDestination(destination); - } - - functions_->glBindTexture(GL_TEXTURE_2D, source->id().value()); - - program->bind(); - - qCritical() << "OpenGLRenderer::Blit is a stub!"; - - program->release(); - - functions_->glBindTexture(GL_TEXTURE_2D, 0); - - if (destination) { - DetachTextureAsDestination(); - } -}*/ - GLint OpenGLRenderer::GetInternalFormat(PixelFormat::Format format) { switch (format) { diff --git a/app/render/backend/opengl/openglrenderer.h b/app/render/backend/opengl/openglrenderer.h index 7634efc4f..12b6e2a40 100644 --- a/app/render/backend/opengl/openglrenderer.h +++ b/app/render/backend/opengl/openglrenderer.h @@ -86,12 +86,6 @@ private: QOffscreenSurface surface_; - QOpenGLVertexArrayObject vao_; - - QOpenGLBuffer vert_vbo_; - - QOpenGLBuffer frag_vbo_; - GLuint framebuffer_; }; diff --git a/app/render/backend/renderer.cpp b/app/render/backend/renderer.cpp index 33897c7b1..b2bf0ee04 100644 --- a/app/render/backend/renderer.cpp +++ b/app/render/backend/renderer.cpp @@ -20,11 +20,9 @@ #include "renderer.h" -#include -namespace OCIO = OCIO_NAMESPACE::v1; - #include +#include "common/ocioutils.h" #include "render/colormanager.h" OLIVE_NAMESPACE_ENTER @@ -54,83 +52,62 @@ const int OCIO_LUT3D_ENTRY_COUNT = 3 * OCIO_LUT3D_PIXEL_COUNT; const int OCIO_LUT3D_ENTRY_COUNT_WITH_ALPHA = 4 * OCIO_LUT3D_PIXEL_COUNT; const int OCIO_LUT2D_EDGE_SIZE = 512;*/ -void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture *destination) +void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture *destination, bool flipped) { + qDebug() << "BlitColorManaged is a partial stub"; + + QVariant shader = CreateNativeShader(ShaderCode(FileFunctions::ReadFileAsString(":/shaders/default.frag"), FileFunctions::ReadFileAsString(":/shaders/default.vert"))); + + ShaderJob job; + job.InsertValue(QStringLiteral("ove_maintex"), ShaderValue(QVariant::fromValue(source), NodeParam::kTexture)); + + if (flipped) { + QMatrix4x4 mat; + mat.scale(1, -1, 1); + job.SetMatrix(mat); + } + + BlitToTexture(shader, job, destination); + + DestroyNativeShader(shader); +} + +void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params, bool flipped) +{ + qDebug() << "BlitColorManaged is a partial stub"; + /*ColorContext color_ctx; if (color_cache_.contains(color_processor->id())) { color_ctx = color_cache_.value(color_processor->id()); } else { - // Generate OCIO color context - - // Generate OCIO shader descriptor + // Create shader description const char* ocio_func_name = "OCIODisplay"; - OCIO::GpuShaderDesc shader_desc; - shader_desc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0); - shader_desc.setFunctionName(ocio_func_name); - shader_desc.setLut3DEdgeLen(OCIO_LUT3D_EDGE_SIZE); + OCIO::GpuShaderDescRcPtr shader_desc = OCIO::GpuShaderDesc::CreateShaderDesc(); + shader_desc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_2); + shader_desc->setFunctionName(ocio_func_name); + shader_desc->setResourcePrefix("ocio_"); - // Generate LUT - QVector lut_data(OCIO_LUT3D_ENTRY_COUNT); - color_processor->GetProcessor()->getGpuLut3D(lut_data.data(), shader_desc); + // Generate shader + color_processor->GetProcessor()->getDefaultGPUProcessor()->extractGpuShaderInfo(shader_desc); - // Convert to half float RGBA - QVector texture_ready_lut_data(OCIO_LUT3D_ENTRY_COUNT_WITH_ALPHA); - for (int i=0; iGetProcessor()->getGpuShaderText(shader_desc); - ocio_code.replace(QStringLiteral("texture3D"), QStringLiteral("texture2D")); - ocio_code.replace(QStringLiteral("sampler3D"), QStringLiteral("sampler2D")); - - - - qDebug() << frag_code; - - //qDebug() << "FIXME: GPU doesn't handle associated alpha yet"; + qDebug() << "Shader:" << shader_desc->getShaderText(); }*/ - qDebug() << "BlitColorManaged is a partial stub"; - QVariant shader = CreateNativeShader(ShaderCode(FileFunctions::ReadFileAsString(":/shaders/default.frag"), FileFunctions::ReadFileAsString(":/shaders/default.vert"))); ShaderJob job; job.InsertValue(QStringLiteral("ove_maintex"), ShaderValue(QVariant::fromValue(source), NodeParam::kTexture)); - BlitToTexture(shader, job, destination); -} - -void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params) -{ - qDebug() << "BlitColorManaged is a partial stub"; - - QVariant shader = CreateNativeShader(ShaderCode(FileFunctions::ReadFileAsString(":/shaders/default.frag"), FileFunctions::ReadFileAsString(":/shaders/default.vert"))); - - ShaderJob job; - job.InsertValue(QStringLiteral("ove_maintex"), ShaderValue(QVariant::fromValue(source), NodeParam::kTexture)); + if (flipped) { + QMatrix4x4 mat; + mat.scale(1, -1, 1); + job.SetMatrix(mat); + } Blit(shader, job, params); + + DestroyNativeShader(shader); } OLIVE_NAMESPACE_EXIT diff --git a/app/render/backend/renderer.h b/app/render/backend/renderer.h index 382228244..356299fcb 100644 --- a/app/render/backend/renderer.h +++ b/app/render/backend/renderer.h @@ -135,8 +135,8 @@ public: Blit(shader, job, nullptr, params); } - void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture* destination); - void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params); + void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture* destination, bool flipped = false); + void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params, bool flipped = false); public slots: virtual void PostInit() = 0; diff --git a/app/render/color.cpp b/app/render/color.cpp index 3c47f7e81..67151413e 100644 --- a/app/render/color.cpp +++ b/app/render/color.cpp @@ -24,41 +24,41 @@ OLIVE_NAMESPACE_ENTER -Color Color::fromHsv(const float &h, const float &s, const float &v) +Color Color::fromHsv(const double &h, const double &s, const double &v) { - float C = s * v; - float X = C * (1.0f - abs(fmod(h / 60.0f, 2.0f) - 1.0f)); - float m = v - C; - float Rs, Gs, Bs; + double C = s * v; + double X = C * (1.0 - abs(fmod(h / 60.0, 2.0) - 1.0)); + double m = v - C; + double Rs, Gs, Bs; - if(h >= 0.0f && h < 60.0f) { + if(h >= 0.0 && h < 60.0) { Rs = C; Gs = X; - Bs = 0.0f; + Bs = 0.0; } - else if(h >= 60.0f && h < 120.0f) { + else if(h >= 60.0 && h < 120.0) { Rs = X; Gs = C; - Bs = 0.0f; + Bs = 0.0; } - else if(h >= 120.0f && h < 180.0f) { - Rs = 0.0f; + else if(h >= 120.0 && h < 180.0) { + Rs = 0.0; Gs = C; Bs = X; } - else if(h >= 180.0f && h < 240.0f) { - Rs = 0.0f; + else if(h >= 180.0 && h < 240.0) { + Rs = 0.0; Gs = X; Bs = C; } - else if(h >= 240.0f && h < 300.0f) { + else if(h >= 240.0 && h < 300.0) { Rs = X; - Gs = 0.0f; + Gs = 0.0; Bs = C; } else { Rs = C; - Gs = 0.0f; + Gs = 0.0; Bs = X; } @@ -78,11 +78,11 @@ Color::Color(const QColor &c) set_alpha(c.alphaF()); } -void Color::toHsv(float *hue, float *sat, float *val) const +void Color::toHsv(double *hue, double *sat, double *val) const { - float fCMax = qMax(qMax(red(), green()), blue()); - float fCMin = qMin(qMin(red(), green()), blue()); - float fDelta = fCMax - fCMin; + double fCMax = qMax(qMax(red(), green()), blue()); + double fCMin = qMin(qMin(red(), green()), blue()); + double fDelta = fCMax - fCMin; if(fDelta > 0) { if(fCMax == red()) { @@ -111,31 +111,31 @@ void Color::toHsv(float *hue, float *sat, float *val) const } } -float Color::hsv_hue() const +double Color::hsv_hue() const { - float h, s, v; + double h, s, v; toHsv(&h, &s, &v); return h; } -float Color::hsv_saturation() const +double Color::hsv_saturation() const { - float h, s, v; + double h, s, v; toHsv(&h, &s, &v); return s; } -float Color::value() const +double Color::value() const { - float h, s, v; + double h, s, v; toHsv(&h, &s, &v); return v; } -void Color::toHsl(float *hue, float *sat, float *lightness) const +void Color::toHsl(double *hue, double *sat, double *lightness) const { - float fCMin = qMin(red(), qMin(green(), blue())); - float fCMax = qMax(red(), qMax(green(), blue())); + double fCMin = qMin(red(), qMin(green(), blue())); + double fCMax = qMax(red(), qMax(green(), blue())); *lightness = 0.5 * (fCMin + fCMax); @@ -173,30 +173,30 @@ void Color::toHsl(float *hue, float *sat, float *lightness) const } } -float Color::hsl_hue() const +double Color::hsl_hue() const { - float h, s, l; + double h, s, l; toHsl(&h, &s, &l); return h; } -float Color::hsl_saturation() const +double Color::hsl_saturation() const { - float h, s, l; + double h, s, l; toHsl(&h, &s, &l); return s; } -float Color::lightness() const +double Color::lightness() const { - float h, s, l; + double h, s, l; toHsl(&h, &s, &l); return l; } void Color::toData(char *data, const PixelFormat::Format &format) const { - OIIO::convert_types(OIIO::TypeDesc::FLOAT, + OIIO::convert_types(OIIO::TypeDesc::DOUBLE, data_, PixelFormat::GetOIIOTypeDesc(format), data, @@ -209,7 +209,7 @@ Color Color::fromData(const char *data, const PixelFormat::Format &format) OIIO::convert_types(PixelFormat::GetOIIOTypeDesc(format), data, - OIIO::TypeDesc::FLOAT, + OIIO::TypeDesc::DOUBLE, c.data_, kRGBAChannels); @@ -221,17 +221,17 @@ QColor Color::toQColor() const QColor c; // QColor only supports values from 0.0 to 1.0 and are only used for UI representations - c.setRedF(clamp(red(), 0.0f, 1.0f)); - c.setGreenF(clamp(green(), 0.0f, 1.0f)); - c.setBlueF(clamp(blue(), 0.0f, 1.0f)); - c.setAlphaF(clamp(alpha(), 0.0f, 1.0f)); + c.setRedF(clamp(red(), 0.0, 1.0)); + c.setGreenF(clamp(green(), 0.0, 1.0)); + c.setBlueF(clamp(blue(), 0.0, 1.0)); + c.setAlphaF(clamp(alpha(), 0.0, 1.0)); return c; } -float Color::GetRoughLuminance() const +double Color::GetRoughLuminance() const { - return (2*red()+blue()+3*green())/6.0f; + return (2*red()+blue()+3*green())/6.0; } const Color &Color::operator+=(const Color &rhs) @@ -252,7 +252,7 @@ const Color &Color::operator-=(const Color &rhs) return *this; } -const Color &Color::operator*=(const float &rhs) +const Color &Color::operator*=(const double &rhs) { for (int i=0;igetDefaultLumaCoefs(rgb); } @@ -320,16 +320,6 @@ Color ColorManager::GetDefaultLumaCoefs() const return c; } -ColorManager::OCIOMethod ColorManager::GetOCIOMethodForMode(RenderMode::Mode mode) -{ - return static_cast(Core::GetPreferenceForRenderMode(mode, QStringLiteral("OCIOMethod")).toInt()); -} - -void ColorManager::SetOCIOMethodForMode(RenderMode::Mode mode, ColorManager::OCIOMethod method) -{ - Core::SetPreferenceForRenderMode(mode, QStringLiteral("OCIOMethod"), method); -} - void ColorManager::AssociateAlphaPixFmtFilter(ColorManager::AlphaAction action, FramePtr f) { int pixel_count = f->width() * f->height() * kRGBAChannels; diff --git a/app/render/colormanager.h b/app/render/colormanager.h index b8eecdda3..c0ffab26d 100644 --- a/app/render/colormanager.h +++ b/app/render/colormanager.h @@ -82,18 +82,9 @@ public: static QStringList ListAvailableColorspaces(OCIO::ConstConfigRcPtr config); - void GetDefaultLumaCoefs(float* rgb) const; + void GetDefaultLumaCoefs(double *rgb) const; Color GetDefaultLumaCoefs() const; - enum OCIOMethod { - kOCIOFast, - kOCIOAccurate - }; - - static OCIOMethod GetOCIOMethodForMode(RenderMode::Mode mode); - - static void SetOCIOMethodForMode(RenderMode::Mode mode, OCIOMethod method); - class SetLocale { public: diff --git a/app/render/colorprocessor.cpp b/app/render/colorprocessor.cpp index e33942fd2..6ea08ff41 100644 --- a/app/render/colorprocessor.cpp +++ b/app/render/colorprocessor.cpp @@ -33,19 +33,35 @@ ColorProcessor::ColorProcessor(ColorManager *config, const QString &input, const const QString& view = (transform.view().isEmpty()) ? config->GetDefaultView(output) : transform.view(); - OCIO::DisplayTransformRcPtr display_transform = OCIO::DisplayTransform::Create(); + auto display_transform = OCIO::DisplayViewTransform::Create(); - display_transform->setInputColorSpaceName(input.toUtf8()); + display_transform->setSrc(input.toUtf8()); display_transform->setDisplay(output.toUtf8()); display_transform->setView(view.toUtf8()); - if (!transform.look().isEmpty()) { - display_transform->setLooksOverride(transform.look().toUtf8()); - display_transform->setLooksOverrideEnabled(true); - } - OCIO_SET_C_LOCALE_FOR_SCOPE; - processor_ = config->GetConfig()->getProcessor(display_transform); + + if (transform.look().isEmpty()) { + processor_ = config->GetConfig()->getProcessor(display_transform); + } else { + auto group = OCIO::GroupTransform::Create(); + + const char* out_cs = OCIO::LookTransform::GetLooksResultColorSpace(config->GetConfig(), + config->GetConfig()->getCurrentContext(), + transform.look().toUtf8()); + + auto lt = OCIO::LookTransform::Create(); + lt->setSrc(input.toUtf8()); + lt->setDst(out_cs); + lt->setLooks(transform.look().toUtf8()); + lt->setSkipColorSpaceConversion(false); + group->appendTransform(lt); + + display_transform->setSrc(out_cs); + group->appendTransform(display_transform); + + processor_ = config->GetConfig()->getProcessor(group); + } } else { @@ -55,26 +71,39 @@ ColorProcessor::ColorProcessor(ColorManager *config, const QString &input, const } + cpu_processor_ = processor_->getDefaultCPUProcessor(); id_ = GenerateID(config, input, transform); } void ColorProcessor::ConvertFrame(Frame *f) { - OCIO::PackedImageDesc img(reinterpret_cast(f->data()), + OCIO::BitDepth ocio_bit_depth = PixelFormat::GetOCIOBitDepthFromPixelFormat(f->format()); + + if (ocio_bit_depth == OCIO::BIT_DEPTH_UNKNOWN) { + qCritical() << "Tried to color convert frame with no format"; + return; + } + + OCIO::PackedImageDesc img(f->data(), f->width(), f->height(), kRGBAChannels, + ocio_bit_depth, OCIO::AutoStride, OCIO::AutoStride, f->linesize_bytes()); - processor_->apply(img); + cpu_processor_->apply(img); } -Color ColorProcessor::ConvertColor(Color in) +Color ColorProcessor::ConvertColor(const Color& in) { - processor_->applyRGBA(in.data()); - return in; + // I've been bamboozled + float c[4] = {float(in.red()), float(in.green()), float(in.blue()), float(in.alpha())}; + + cpu_processor_->applyRGBA(c); + + return Color(c[0], c[1], c[2], c[3]); } QString ColorProcessor::GenerateID(ColorManager *config, const QString &input, const ColorTransform &transform) diff --git a/app/render/colorprocessor.h b/app/render/colorprocessor.h index f2c2e6a2e..5d0b9a8f1 100644 --- a/app/render/colorprocessor.h +++ b/app/render/colorprocessor.h @@ -22,6 +22,7 @@ #define COLORPROCESSOR_H #include "codec/frame.h" +#include "common/ocioutils.h" #include "render/color.h" #include "render/colortransform.h" @@ -51,7 +52,7 @@ public: void ConvertFrame(FramePtr f); void ConvertFrame(Frame* f); - Color ConvertColor(Color in); + Color ConvertColor(const Color &in); const QString& id() const { @@ -63,6 +64,8 @@ public: private: OCIO::ConstProcessorRcPtr processor_; + OCIO::ConstCPUProcessorRcPtr cpu_processor_; + QString id_; }; diff --git a/app/render/colortransform.h b/app/render/colortransform.h index 45e605c8d..e0aa67f83 100644 --- a/app/render/colortransform.h +++ b/app/render/colortransform.h @@ -21,11 +21,10 @@ #ifndef COLORTRANSFORM_H #define COLORTRANSFORM_H -#include - #include #include "common/define.h" +#include "common/ocioutils.h" OLIVE_NAMESPACE_ENTER diff --git a/app/render/pixelformat.cpp b/app/render/pixelformat.cpp index 9cde0a269..9aee69783 100644 --- a/app/render/pixelformat.cpp +++ b/app/render/pixelformat.cpp @@ -86,6 +86,28 @@ QString PixelFormat::GetName(const PixelFormat::Format &format) return tr("Unknown (%1)").arg(format); } +OCIO::BitDepth PixelFormat::GetOCIOBitDepthFromPixelFormat(PixelFormat::Format format) +{ + switch (format) { + case PixelFormat::PIX_FMT_RGBA8: + return OCIO::BIT_DEPTH_UINT8; + case PixelFormat::PIX_FMT_RGBA16U: + return OCIO::BIT_DEPTH_UINT16; + break; + case PixelFormat::PIX_FMT_RGBA16F: + return OCIO::BIT_DEPTH_F16; + break; + case PixelFormat::PIX_FMT_RGBA32F: + return OCIO::BIT_DEPTH_F32; + break; + case PixelFormat::PIX_FMT_INVALID: + case PixelFormat::PIX_FMT_COUNT: + break; + } + + return OCIO::BIT_DEPTH_UNKNOWN; +} + PixelFormat* PixelFormat::instance_ = nullptr; void PixelFormat::CreateInstance() diff --git a/app/render/pixelformat.h b/app/render/pixelformat.h index 4808aa35a..c60027c93 100644 --- a/app/render/pixelformat.h +++ b/app/render/pixelformat.h @@ -26,6 +26,7 @@ #include #include +#include "common/ocioutils.h" #include "render/rendermodes.h" OLIVE_NAMESPACE_ENTER @@ -116,6 +117,8 @@ public: */ static QString GetName(const Format& format); + static OCIO::BitDepth GetOCIOBitDepthFromPixelFormat(PixelFormat::Format format); + signals: void FormatChanged(); diff --git a/app/render/previewautocacher.cpp b/app/render/previewautocacher.cpp index cbf09a06f..eb673f8c8 100644 --- a/app/render/previewautocacher.cpp +++ b/app/render/previewautocacher.cpp @@ -585,7 +585,9 @@ void PreviewAutoCacher::TryRender() watcher->SetTicket(RenderManager::instance()->RenderFrame(copied_viewer_node_, color_manager_, single_frame_render_->property("time").value(), - RenderMode::kOffline, true)); + RenderMode::kOffline, + viewer_node_->video_frame_cache(), + true)); single_frame_render_ = nullptr; } @@ -626,7 +628,9 @@ void PreviewAutoCacher::RequeueFrames() video_tasks_.insert(watcher, hash); watcher->SetTicket(RenderManager::instance()->RenderFrame(copied_viewer_node_, color_manager_, - t, RenderMode::kOffline, false)); + t, RenderMode::kOffline, + viewer_node_->video_frame_cache(), + false)); } } diff --git a/app/render/rendermanager.cpp b/app/render/rendermanager.cpp index 9ad31cd65..2aa648fd5 100644 --- a/app/render/rendermanager.cpp +++ b/app/render/rendermanager.cpp @@ -93,7 +93,7 @@ QByteArray RenderManager::Hash(const Node *n, const VideoParams ¶ms, const r return hasher.result(); } -RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager *color_manager, const rational &time, RenderMode::Mode mode, bool prioritize) +RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager *color_manager, const rational &time, RenderMode::Mode mode, FrameHashCache *cache, bool prioritize) { return RenderFrame(viewer, color_manager, @@ -101,10 +101,11 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager *c mode, QSize(0, 0), QMatrix4x4(), + cache, prioritize); } -RenderTicketPtr RenderManager::RenderFrame(ViewerOutput* viewer, ColorManager* color_manager, const rational &time, RenderMode::Mode mode, const QSize &force_size, const QMatrix4x4 &matrix, bool prioritize) +RenderTicketPtr RenderManager::RenderFrame(ViewerOutput* viewer, ColorManager* color_manager, const rational &time, RenderMode::Mode mode, const QSize &force_size, const QMatrix4x4 &matrix, FrameHashCache *cache, bool prioritize) { // Create ticket RenderTicketPtr ticket = std::make_shared(); @@ -115,7 +116,7 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput* viewer, ColorManager* c ticket->setProperty("matrix", matrix); ticket->setProperty("mode", mode); ticket->setProperty("type", kTypeVideo); - ticket->setProperty("cache", viewer->video_frame_cache()->GetCacheDirectory()); + ticket->setProperty("cache", cache->GetCacheDirectory()); ticket->setProperty("colormanager", Node::PtrToValue(color_manager)); // Queue appending the ticket and running the next job on our thread to make this function thread-safe diff --git a/app/render/rendermanager.h b/app/render/rendermanager.h index 5277c83bd..f170e2aa2 100644 --- a/app/render/rendermanager.h +++ b/app/render/rendermanager.h @@ -80,8 +80,8 @@ public: * * This function is thread-safe. */ - RenderTicketPtr RenderFrame(ViewerOutput* viewer, ColorManager* color_manager, const rational& time, RenderMode::Mode mode, bool prioritize = false); - RenderTicketPtr RenderFrame(ViewerOutput* viewer, ColorManager* color_manager, const rational& time, RenderMode::Mode mode, const QSize& force_size, const QMatrix4x4& matrix, bool prioritize = false); + RenderTicketPtr RenderFrame(ViewerOutput* viewer, ColorManager* color_manager, const rational& time, RenderMode::Mode mode, FrameHashCache* cache = nullptr, bool prioritize = false); + RenderTicketPtr RenderFrame(ViewerOutput* viewer, ColorManager* color_manager, const rational& time, RenderMode::Mode mode, const QSize& force_size, const QMatrix4x4& matrix, FrameHashCache* cache = nullptr, bool prioritize = false); /** * @brief Asynchronously generate a chunk of audio diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp index e18712446..34b612ec6 100644 --- a/app/render/renderprocessor.cpp +++ b/app/render/renderprocessor.cpp @@ -297,7 +297,7 @@ QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational & qDebug() << "FIXME: Accessing video_stream->colorspace() may cause race conditions"; - ColorManager* color_manager = video_stream->footage()->project()->color_manager(); + ColorManager* color_manager = Node::ValueToPtr(ticket_->property("colormanager")); ColorProcessorPtr processor = ColorProcessor::Create(color_manager, video_stream->colorspace(), ColorTransform(OCIO::ROLE_SCENE_LINEAR)); @@ -434,7 +434,7 @@ QVariant RenderProcessor::ProcessFrameGeneration(const Node *node, const Generat QVariant RenderProcessor::GetCachedFrame(const Node *node, const rational &time) { - if (ticket_->property("mode").toInt() == RenderMode::kOffline + if (!ticket_->property("cache").toString().isEmpty() && node->id() == QStringLiteral("org.olivevideoeditor.Olive.videoinput")) { const VideoParams& video_params = Node::ValueToPtr(ticket_->property("viewer"))->video_params(); @@ -442,6 +442,8 @@ QVariant RenderProcessor::GetCachedFrame(const Node *node, const rational &time) FramePtr f = FrameHashCache::LoadCacheFrame(ticket_->property("cache").toString(), hash); + qDebug() << ticket_->property("cache").toString() << hash.toHex(); + if (f) { // The cached frame won't load with the correct divider by default, so we enforce it here VideoParams p = f->video_params(); @@ -452,8 +454,12 @@ QVariant RenderProcessor::GetCachedFrame(const Node *node, const rational &time) f->set_video_params(p); + qDebug() << "Using cached frame!"; + Renderer::TexturePtr texture = render_ctx_->CreateTexture(f->video_params(), f->data(), f->linesize_pixels()); return QVariant::fromValue(texture); + } else { + qDebug() << "Not using cached frame because frame is null"; } } diff --git a/app/render/shaderinfo.h b/app/render/shaderinfo.h index 680b32bef..3dc69f681 100644 --- a/app/render/shaderinfo.h +++ b/app/render/shaderinfo.h @@ -1,6 +1,8 @@ #ifndef SHADERINFO_H #define SHADERINFO_H +#include + #include "codec/samplebuffer.h" #include "common/filefunctions.h" #include "node/input.h" @@ -142,6 +144,16 @@ public: bilinear_ = true; } + const QMatrix4x4& GetMatrix() const + { + return matrix_; + } + + void SetMatrix(const QMatrix4x4& matrix) + { + matrix_ = matrix; + } + const QString& GetShaderID() const { return shader_id_; @@ -192,6 +204,8 @@ private: bool bilinear_; + QMatrix4x4 matrix_; + }; class ShaderCode { diff --git a/app/task/export/export.cpp b/app/task/export/export.cpp index a74445eab..d5da32ae5 100644 --- a/app/task/export/export.cpp +++ b/app/task/export/export.cpp @@ -114,11 +114,6 @@ bool ExportTask::Run() void FrameColorConvert(ColorProcessorPtr processor, FramePtr frame) { - // OCIO conversion requires a frame in 32F format - if (frame->format() != PixelFormat::PIX_FMT_RGBA32F) { - frame = PixelFormat::ConvertPixelFormat(frame, PixelFormat::PIX_FMT_RGBA32F); - } - // Color conversion must be done with unassociated alpha, and the pipeline is always associated ColorManager::DisassociateAlpha(frame); diff --git a/app/task/project/loadotio/loadotio.cpp b/app/task/project/loadotio/loadotio.cpp index 78799e389..8efcc91aa 100644 --- a/app/task/project/loadotio/loadotio.cpp +++ b/app/task/project/loadotio/loadotio.cpp @@ -166,7 +166,7 @@ bool LoadOTIOTask::Run() if (imported_footage.contains(footage_url)) { probed_item = imported_footage.value(footage_url); } else { - probed_item = Decoder::ProbeMedia(project_.get(), footage_url, &IsCancelled()); + probed_item = Decoder::Probe(project_.get(), footage_url, &IsCancelled()); imported_footage.insert(footage_url, probed_item); project_->root()->add_child(probed_item); } diff --git a/app/threading/threadpool.cpp b/app/threading/threadpool.cpp index b89a00ee9..9e7f26206 100644 --- a/app/threading/threadpool.cpp +++ b/app/threading/threadpool.cpp @@ -114,7 +114,7 @@ void ThreadPoolThread::RunTicket(RenderTicketPtr ticket) void ThreadPoolThread::run() { - while (!IsCancelled()) { + while (true) { wait_cond_.wait(&mutex_); if (ticket_) { @@ -122,7 +122,11 @@ void ThreadPoolThread::run() ticket_ = nullptr; } - emit Done(); + if (IsCancelled()) { + break; + } else { + emit Done(); + } } } diff --git a/app/widget/colorwheel/colorgradientwidget.cpp b/app/widget/colorwheel/colorgradientwidget.cpp index 82883eb69..e7b0579d9 100644 --- a/app/widget/colorwheel/colorgradientwidget.cpp +++ b/app/widget/colorwheel/colorgradientwidget.cpp @@ -76,7 +76,7 @@ void ColorGradientWidget::paintEvent(QPaintEvent *e) p.setPen(QPen(GetUISelectorColor(), qMax(1, selector_radius / 2))); p.setBrush(Qt::NoBrush); - float clamped_val = clamp(val_, 0.0f, 1.0f); + double clamped_val = clamp(val_, 0.0, 1.0); if (orientation_ == Qt::Horizontal) { p.drawRect(qRound(width() * (1.0 - clamped_val)) - selector_radius, 0, selector_radius * 2, height() - 1); @@ -87,7 +87,7 @@ void ColorGradientWidget::paintEvent(QPaintEvent *e) void ColorGradientWidget::SelectedColorChangedEvent(const Color &c, bool external) { - float hue, sat; + double hue, sat; c.toHsv(&hue, &sat, &val_); diff --git a/app/widget/colorwheel/colorgradientwidget.h b/app/widget/colorwheel/colorgradientwidget.h index 725b662fe..26f162912 100644 --- a/app/widget/colorwheel/colorgradientwidget.h +++ b/app/widget/colorwheel/colorgradientwidget.h @@ -50,7 +50,7 @@ private: Color end_; - float val_; + double val_; }; diff --git a/app/widget/colorwheel/colorwheelwidget.cpp b/app/widget/colorwheel/colorwheelwidget.cpp index 4edf774f3..f5e5e2a32 100644 --- a/app/widget/colorwheel/colorwheelwidget.cpp +++ b/app/widget/colorwheel/colorwheelwidget.cpp @@ -121,7 +121,7 @@ void ColorWheelWidget::SelectedColorChangedEvent(const Color &c, bool external) { if (external) { force_redraw_ = true; - val_ = clamp(c.value(), 0.0f, 1.0f); + val_ = clamp(c.value(), 0.0, 1.0); } } @@ -159,7 +159,7 @@ Color ColorWheelWidget::GetColorFromTriangle(const ColorWheelWidget::Triangle &t QPoint ColorWheelWidget::GetCoordsFromColor(const Color &c) const { - float hue, sat, val; + double hue, sat, val; c.toHsv(&hue, &sat, &val); qreal hypotenuse = sat * GetRadius(); diff --git a/app/widget/manageddisplay/manageddisplay.h b/app/widget/manageddisplay/manageddisplay.h index 26c122df7..55da88103 100644 --- a/app/widget/manageddisplay/manageddisplay.h +++ b/app/widget/manageddisplay/manageddisplay.h @@ -170,6 +170,11 @@ protected: void doneCurrent(); + QWidget* inner_widget() const + { + return inner_widget_; + } + protected slots: /** * @brief Called whenever the internal rendering context has been created diff --git a/app/widget/scope/histogram/histogram.cpp b/app/widget/scope/histogram/histogram.cpp index 04255a275..aed0d6988 100644 --- a/app/widget/scope/histogram/histogram.cpp +++ b/app/widget/scope/histogram/histogram.cpp @@ -92,7 +92,7 @@ void HistogramScope::DrawScope(Renderer::TexturePtr managed_tex, QVariant pipeli renderer()->Blit(pipeline_secondary_, shader_job, texture_row_sums_->params()); // Draw line overlays - QPainter p(this); + QPainter p(inner_widget()); QFont font = p.font(); font.setPixelSize(10); QFontMetrics font_metrics = QFontMetrics(font); diff --git a/app/widget/scope/waveform/waveform.cpp b/app/widget/scope/waveform/waveform.cpp index 618ed64b8..3f9f85afc 100644 --- a/app/widget/scope/waveform/waveform.cpp +++ b/app/widget/scope/waveform/waveform.cpp @@ -60,7 +60,7 @@ void WaveformScope::DrawScope(Renderer::TexturePtr managed_tex, QVariant pipelin ShaderValue(QVector2D(width(), height()), NodeParam::kVec2)); // Set luma coefficients - float luma_coeffs[3] = {0.0f, 0.0f, 0.0f}; + double luma_coeffs[3] = {0.0f, 0.0f, 0.0f}; color_manager()->GetDefaultLumaCoefs(luma_coeffs); job.InsertValue(QStringLiteral("luma_coeffs"), ShaderValue(QVector3D(luma_coeffs[0], luma_coeffs[1], luma_coeffs[2]), NodeParam::kVec3)); @@ -85,7 +85,7 @@ void WaveformScope::DrawScope(Renderer::TexturePtr managed_tex, QVariant pipelin float waveform_end_dim_x = (width() - 1.0) - waveform_start_dim_x; // Draw line overlays - QPainter p(this); + QPainter p(inner_widget()); QFont font; font.setPixelSize(10); QFontMetrics font_metrics = QFontMetrics(font); diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 8e47ee9c9..ed83de293 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -392,6 +392,7 @@ FramePtr ViewerWidget::DecodeCachedImage(const QString &fn, const rational& time void ViewerWidget::DecodeCachedImage(RenderTicketPtr ticket, const QString &fn, const rational& time) const { + ticket->Start(); ticket->Finish(QVariant::fromValue(DecodeCachedImage(fn, time)), false); } diff --git a/app/widget/viewer/viewerdisplay.cpp b/app/widget/viewer/viewerdisplay.cpp index b4fb272f7..1e8400ba6 100644 --- a/app/widget/viewer/viewerdisplay.cpp +++ b/app/widget/viewer/viewerdisplay.cpp @@ -108,7 +108,7 @@ void ViewerDisplayWidget::SetImage(FramePtr in_buffer) || texture_->format() != in_buffer->format()) { texture_ = renderer()->CreateTexture(in_buffer->video_params(), in_buffer->data(), in_buffer->linesize_pixels()); } else { - texture_->Upload(in_buffer->data(), in_buffer->linesize_bytes()); + texture_->Upload(in_buffer->data(), in_buffer->linesize_pixels()); } doneCurrent(); @@ -298,8 +298,7 @@ void ViewerDisplayWidget::OnPaint() } // Draw texture through color transform - renderer()->BlitColorManaged(color_service(), texture_, VideoParams(width(), height(), PixelFormat::PIX_FMT_RGBA16F)); - + renderer()->BlitColorManaged(color_service(), texture_, VideoParams(width(), height(), PixelFormat::PIX_FMT_RGBA16F), true); } QTransform world_transform = GenerateWorldTransform(); @@ -312,14 +311,14 @@ void ViewerDisplayWidget::OnPaint() gizmo_db_ = gt.GenerateDatabase(gizmos_, TimeRange(node_time, node_time)); - QPainter p(this); + QPainter p(inner_widget()); p.setWorldTransform(world_transform); gizmos_->DrawGizmos(gizmo_db_, &p, QVector2D(GetTexturePosition(size())), size()); } // Draw action/title safe areas if (safe_margin_.is_enabled()) { - QPainter p(this); + QPainter p(inner_widget()); p.setWorldTransform(world_transform); p.setPen(Qt::lightGray);