completed color management implementation
This commit adds the background functionality of the render cache invalidating whenever a footage's color space is changed. This includes when the project's configuration is changed as well.
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include <QCheckBox>
|
||||
#include <QSpinBox>
|
||||
|
||||
#include "render/colormanager.h"
|
||||
#include "streamproperties/audiostreamproperties.h"
|
||||
#include "streamproperties/videostreamproperties.h"
|
||||
#include "undo/undostack.h"
|
||||
|
||||
@@ -20,10 +20,13 @@
|
||||
|
||||
#include "media.h"
|
||||
|
||||
MediaInput::MediaInput()
|
||||
MediaInput::MediaInput() :
|
||||
connected_footage_(nullptr)
|
||||
{
|
||||
footage_input_ = new NodeInput("footage_in");
|
||||
footage_input_->set_data_type(NodeInput::kFootage);
|
||||
footage_input_->SetConnectable(false);
|
||||
connect(footage_input_, SIGNAL(ValueChanged(const rational&, const rational&)), this, SLOT(FootageChanged()));
|
||||
AddInput(footage_input_);
|
||||
}
|
||||
|
||||
@@ -41,3 +44,27 @@ void MediaInput::Retranslate()
|
||||
{
|
||||
footage_input_->set_name(tr("Footage"));
|
||||
}
|
||||
|
||||
void MediaInput::FootageChanged()
|
||||
{
|
||||
StreamPtr new_footage = footage_input_->get_value_at_time(0).value<StreamPtr>();
|
||||
|
||||
if (new_footage == connected_footage_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (connected_footage_ != nullptr) {
|
||||
disconnect(connected_footage_.get(), SIGNAL(ColorSpaceChanged()), this, SLOT(FootageColorSpaceChanged()));
|
||||
}
|
||||
|
||||
connected_footage_ = new_footage;
|
||||
|
||||
if (connected_footage_ != nullptr) {
|
||||
connect(connected_footage_.get(), SIGNAL(ColorSpaceChanged()), this, SLOT(FootageColorSpaceChanged()));
|
||||
}
|
||||
}
|
||||
|
||||
void MediaInput::FootageColorSpaceChanged()
|
||||
{
|
||||
InvalidateCache(0, RATIONAL_MAX, footage_input_);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,13 @@ public:
|
||||
protected:
|
||||
NodeInput* footage_input_;
|
||||
|
||||
StreamPtr connected_footage_;
|
||||
|
||||
private slots:
|
||||
void FootageChanged();
|
||||
|
||||
void FootageColorSpaceChanged();
|
||||
|
||||
};
|
||||
|
||||
#endif // MEDIAINPUT_H
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "imagestream.h"
|
||||
|
||||
#include "footage.h"
|
||||
#include "project/project.h"
|
||||
#include "render/colormanager.h"
|
||||
|
||||
ImageStream::ImageStream() :
|
||||
@@ -69,7 +71,11 @@ void ImageStream::set_premultiplied_alpha(bool e)
|
||||
|
||||
const QString &ImageStream::colorspace()
|
||||
{
|
||||
return colorspace_;
|
||||
if (colorspace_.isEmpty()) {
|
||||
return footage()->project()->default_input_colorspace();
|
||||
} else {
|
||||
return colorspace_;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageStream::set_colorspace(const QString &color)
|
||||
@@ -81,6 +87,15 @@ void ImageStream::set_colorspace(const QString &color)
|
||||
|
||||
void ImageStream::ColorConfigChangedSlot()
|
||||
{
|
||||
// FIXME: Update colorspace correctly
|
||||
colorspace_.clear();
|
||||
// Check if this colorspace is in the new config
|
||||
if (!colorspace_.isEmpty()) {
|
||||
QStringList colorspaces = ColorManager::ListAvailableInputColorspaces(OCIO::GetCurrentConfig());
|
||||
if (!colorspaces.contains(colorspace_)) {
|
||||
// Set to empty if not
|
||||
colorspace_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Either way, the color calculation has likely changed so we signal here
|
||||
emit ColorSpaceChanged();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
#include "item.h"
|
||||
|
||||
Item::Item() :
|
||||
parent_(nullptr)
|
||||
parent_(nullptr),
|
||||
project_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -127,6 +128,18 @@ const Item *Item::root() const
|
||||
return item;
|
||||
}
|
||||
|
||||
Project *Item::project() const
|
||||
{
|
||||
const Item* root_item = root();
|
||||
|
||||
return root_item->project_;
|
||||
}
|
||||
|
||||
void Item::set_project(Project *project)
|
||||
{
|
||||
project_ = project;
|
||||
}
|
||||
|
||||
bool Item::CanHaveChildren() const
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include "common/threadedobject.h"
|
||||
|
||||
class Project;
|
||||
|
||||
class Item;
|
||||
using ItemPtr = std::shared_ptr<Item>;
|
||||
|
||||
@@ -101,6 +103,9 @@ public:
|
||||
Item *parent() const;
|
||||
const Item* root() const;
|
||||
|
||||
Project* project() const;
|
||||
void set_project(Project* project);
|
||||
|
||||
virtual bool CanHaveChildren() const;
|
||||
|
||||
bool ChildExistsWithName(const QString& name);
|
||||
@@ -112,6 +117,8 @@ private:
|
||||
|
||||
Item* parent_;
|
||||
|
||||
Project* project_;
|
||||
|
||||
QString name_;
|
||||
|
||||
QString tooltip_;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
Project::Project()
|
||||
{
|
||||
name_ = tr("(untitled)");
|
||||
root_.set_project(this);
|
||||
}
|
||||
|
||||
Folder *Project::root()
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
#include "render/colorprocessor.h"
|
||||
#include "rendercache.h"
|
||||
|
||||
using ColorProcessorCache = RenderCache<Stream*, ColorProcessorPtr>;
|
||||
using ColorProcessorCache = RenderCache<QString, ColorProcessorPtr>;
|
||||
|
||||
#endif // COLORPROCESSORCACHE_H
|
||||
|
||||
@@ -55,9 +55,6 @@ bool OpenGLWorker::InitInternal()
|
||||
|
||||
void OpenGLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable *table)
|
||||
{
|
||||
// Set up OCIO context
|
||||
OpenGLColorProcessorPtr color_processor = std::static_pointer_cast<OpenGLColorProcessor>(color_cache()->Get(stream.get()));
|
||||
|
||||
// Ensure stream is video or image type
|
||||
if (stream->type() != Stream::kVideo && stream->type() != Stream::kImage) {
|
||||
return;
|
||||
@@ -65,16 +62,13 @@ void OpenGLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable
|
||||
|
||||
ImageStreamPtr video_stream = std::static_pointer_cast<ImageStream>(stream);
|
||||
|
||||
if (!color_processor) {
|
||||
QString input_colorspace = video_stream->colorspace();
|
||||
if (input_colorspace.isEmpty()) {
|
||||
// FIXME: Should use Stream->Footage to find the Project* since that's a direct chain
|
||||
input_colorspace = olive::core.GetActiveProject()->default_input_colorspace();
|
||||
}
|
||||
// Set up OCIO context
|
||||
OpenGLColorProcessorPtr color_processor = std::static_pointer_cast<OpenGLColorProcessor>(color_cache()->Get(video_stream->colorspace()));
|
||||
|
||||
color_processor = OpenGLColorProcessor::CreateOpenGL(input_colorspace,
|
||||
if (!color_processor) {
|
||||
color_processor = OpenGLColorProcessor::CreateOpenGL(video_stream->colorspace(),
|
||||
OCIO::ROLE_SCENE_LINEAR);
|
||||
color_cache()->Add(stream.get(), color_processor);
|
||||
color_cache()->Add(video_stream->colorspace(), color_processor);
|
||||
}
|
||||
|
||||
// OCIO's CPU conversion is more accurate, so for online we render on CPU but offline we render GPU
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "common/define.h"
|
||||
#include "node/node.h"
|
||||
#include "project/project.h"
|
||||
#include "render/pixelservice.h"
|
||||
|
||||
VideoRenderWorker::VideoRenderWorker(VideoRenderFrameCache *frame_cache, QObject *parent) :
|
||||
@@ -102,8 +103,8 @@ void VideoRenderWorker::HashNodeRecursively(QCryptographicHash *hash, const Node
|
||||
// Footage timestamp
|
||||
hash->addData(QString::number(decoder->GetTimestampFromTime(input_time)).toUtf8());
|
||||
|
||||
// Current colorspace
|
||||
// FIXME: Handle empty colorspace...
|
||||
// Current color config and space
|
||||
hash->addData(video_stream->footage()->project()->ocio_config().toUtf8());
|
||||
hash->addData(video_stream->colorspace().toUtf8());
|
||||
|
||||
// Alpha associated setting
|
||||
|
||||
Reference in New Issue
Block a user