Add hardware decoding support
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "ociolut.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QMetaObject>
|
||||
|
||||
#include "node/color/colormanager/colormanager.h"
|
||||
|
||||
@@ -54,6 +55,8 @@ OCIOLutNode::OCIOLutNode()
|
||||
|
||||
AddInput(kDirectionInput, NodeValue::kCombo, 0,
|
||||
InputFlags(kInputFlagNotKeyframable | kInputFlagNotConnectable));
|
||||
|
||||
qRegisterMetaType<olive::ColorProcessorPtr>();
|
||||
}
|
||||
|
||||
QString OCIOLutNode::Name() const
|
||||
@@ -102,14 +105,29 @@ void OCIOLutNode::ConfigChanged()
|
||||
|
||||
void OCIOLutNode::GenerateProcessor()
|
||||
{
|
||||
QMutexLocker locker(&gen_mutex_);
|
||||
|
||||
if (!manager()) {
|
||||
set_processor(nullptr);
|
||||
last_processor_.reset();
|
||||
last_path_.clear();
|
||||
last_direction_ = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
const QString path = GetStandardValue(kFileInput).toString();
|
||||
const int direction = GetStandardValue(kDirectionInput).toInt();
|
||||
|
||||
if (path.isEmpty()) {
|
||||
set_processor(nullptr);
|
||||
last_processor_.reset();
|
||||
last_path_.clear();
|
||||
last_direction_ = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-use the existing processor if the file and direction haven't changed.
|
||||
if (path == last_path_ && direction == last_direction_ && last_processor_) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -117,6 +135,9 @@ void OCIOLutNode::GenerateProcessor()
|
||||
if (!info.exists() || !info.isFile()) {
|
||||
qWarning() << "OCIO LUT file does not exist:" << path;
|
||||
set_processor(nullptr);
|
||||
last_processor_.reset();
|
||||
last_path_.clear();
|
||||
last_direction_ = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -124,24 +145,87 @@ void OCIOLutNode::GenerateProcessor()
|
||||
if (!IsSupportedLutExtension(suffix)) {
|
||||
qWarning() << "Unsupported OCIO LUT file extension:" << path;
|
||||
set_processor(nullptr);
|
||||
last_processor_.reset();
|
||||
last_path_.clear();
|
||||
last_direction_ = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
pending_path_ = path;
|
||||
pending_direction_ = direction;
|
||||
pending_generation_++;
|
||||
const int generation = pending_generation_;
|
||||
ColorManager *manager = this->manager();
|
||||
|
||||
locker.unlock();
|
||||
|
||||
QThreadPool::globalInstance()->start(
|
||||
new GenerateProcessorTask(this, path, direction, generation, manager));
|
||||
}
|
||||
|
||||
void OCIOLutNode::SetProcessorResult(ColorProcessorPtr processor,
|
||||
const QString &path, int direction,
|
||||
int generation)
|
||||
{
|
||||
QMutexLocker locker(&gen_mutex_);
|
||||
|
||||
if (generation != pending_generation_) {
|
||||
// A newer request was issued while this one was in flight; ignore.
|
||||
return;
|
||||
}
|
||||
|
||||
if (path != pending_path_ || direction != pending_direction_) {
|
||||
return;
|
||||
}
|
||||
|
||||
last_path_ = path;
|
||||
last_direction_ = direction;
|
||||
last_processor_ = processor;
|
||||
set_processor(processor);
|
||||
}
|
||||
|
||||
OCIOLutNode::GenerateProcessorTask::GenerateProcessorTask(
|
||||
OCIOLutNode *node, const QString &path, int direction, int generation,
|
||||
ColorManager *manager)
|
||||
: node_(node), path_(path), direction_(direction), generation_(generation),
|
||||
manager_(manager)
|
||||
{
|
||||
setAutoDelete(true);
|
||||
}
|
||||
|
||||
void OCIOLutNode::GenerateProcessorTask::run()
|
||||
{
|
||||
ColorProcessorPtr processor = CreateProcessor(path_, direction_, manager_);
|
||||
|
||||
if (node_) {
|
||||
QMetaObject::invokeMethod(
|
||||
node_, "SetProcessorResult", Qt::QueuedConnection,
|
||||
Q_ARG(olive::ColorProcessorPtr, processor), Q_ARG(QString, path_),
|
||||
Q_ARG(int, direction_), Q_ARG(int, generation_));
|
||||
}
|
||||
}
|
||||
|
||||
ColorProcessorPtr OCIOLutNode::GenerateProcessorTask::CreateProcessor(
|
||||
const QString &path, int direction, ColorManager *manager)
|
||||
{
|
||||
if (!manager) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create();
|
||||
transform->setSrc(path.toUtf8().constData());
|
||||
transform->setInterpolation(OCIO::INTERP_LINEAR);
|
||||
transform->setDirection(
|
||||
static_cast<ColorProcessor::Direction>(
|
||||
GetStandardValue(kDirectionInput).toInt()) == ColorProcessor::kNormal
|
||||
static_cast<ColorProcessor::Direction>(direction) ==
|
||||
ColorProcessor::kNormal
|
||||
? OCIO::TRANSFORM_DIR_FORWARD
|
||||
: OCIO::TRANSFORM_DIR_INVERSE);
|
||||
|
||||
set_processor(ColorProcessor::Create(
|
||||
manager()->GetConfig()->getProcessor(transform)));
|
||||
} catch (const OCIO::Exception &e) {
|
||||
return ColorProcessor::Create(manager->GetConfig()->getProcessor(transform));
|
||||
} catch (const std::exception &e) {
|
||||
qWarning() << "OCIO LUT processor error:" << e.what();
|
||||
set_processor(nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
#ifndef OCIOLUTNODE_H
|
||||
#define OCIOLUTNODE_H
|
||||
|
||||
#include <QMutex>
|
||||
#include <QPointer>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
|
||||
#include "node/color/ociobase/ociobase.h"
|
||||
#include "render/colorprocessor.h"
|
||||
|
||||
@@ -41,7 +46,7 @@ public:
|
||||
|
||||
virtual void Retranslate() override;
|
||||
virtual void InputValueChangedEvent(const QString &input,
|
||||
int element) override;
|
||||
int element) override;
|
||||
|
||||
static const QString kFileInput;
|
||||
static const QString kDirectionInput;
|
||||
@@ -49,8 +54,41 @@ public:
|
||||
protected slots:
|
||||
virtual void ConfigChanged() override;
|
||||
|
||||
private slots:
|
||||
void SetProcessorResult(olive::ColorProcessorPtr processor,
|
||||
const QString &path, int direction, int generation);
|
||||
|
||||
private:
|
||||
class GenerateProcessorTask : public QRunnable {
|
||||
public:
|
||||
GenerateProcessorTask(OCIOLutNode *node, const QString &path,
|
||||
int direction, int generation,
|
||||
ColorManager *manager);
|
||||
|
||||
void run() override;
|
||||
|
||||
private:
|
||||
static ColorProcessorPtr CreateProcessor(const QString &path,
|
||||
int direction,
|
||||
ColorManager *manager);
|
||||
|
||||
QPointer<OCIOLutNode> node_;
|
||||
QString path_;
|
||||
int direction_;
|
||||
int generation_;
|
||||
ColorManager *manager_;
|
||||
};
|
||||
|
||||
void GenerateProcessor();
|
||||
|
||||
QMutex gen_mutex_;
|
||||
QString last_path_;
|
||||
int last_direction_ = -1;
|
||||
ColorProcessorPtr last_processor_;
|
||||
|
||||
QString pending_path_;
|
||||
int pending_direction_ = -1;
|
||||
int pending_generation_ = 0;
|
||||
};
|
||||
|
||||
} // namespace olive
|
||||
|
||||
Reference in New Issue
Block a user