upgraded to ocio v2

This commit is contained in:
itsmattkc
2020-11-11 21:53:24 +11:00
parent 0429e70fe0
commit 3c1ac3eeba
40 changed files with 378 additions and 362 deletions
+1 -1
View File
@@ -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;
}
+59 -107
View File
@@ -21,6 +21,7 @@
#include "openglrenderer.h"
#include <QDebug>
#include <QFloat16>
OLIVE_NAMESPACE_ENTER
@@ -44,16 +45,6 @@ const QVector<GLfloat> blit_texcoords = {
1.0f, 1.0f
};
const QVector<GLfloat> 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, &current_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<GLuint>();
const VideoParams& p = texture->params();
GLint current_tex;
functions_->glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_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<NodeValue> nv = value.value< QVector<NodeValue> >();
QVector<QVector2D> a(nv.size());
for (int j=0;j<a.size();j++) {
a[j] = nv.at(j).data().value<QVector2D>();
}
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<QVector2D>());
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<Color>();
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<GLfloat>(destination_params.width()),
static_cast<GLfloat>(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; i<textures_to_bind.size(); i++) {
functions_->glActiveTexture(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<GLfloat>(destination_params.width()),
static_cast<GLfloat>(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<GLuint>());
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<GLuint>());
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<QOpenGLShaderProgram>(shader);
if (!program) {
qCritical() << "Attempted to blit with a null shader";
return;
}
if (destination) {
AttachTextureAsDestination(destination);
}
functions_->glBindTexture(GL_TEXTURE_2D, source->id().value<GLuint>());
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) {
@@ -86,12 +86,6 @@ private:
QOffscreenSurface surface_;
QOpenGLVertexArrayObject vao_;
QOpenGLBuffer vert_vbo_;
QOpenGLBuffer frag_vbo_;
GLuint framebuffer_;
};
+39 -62
View File
@@ -20,11 +20,9 @@
#include "renderer.h"
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE::v1;
#include <QFloat16>
#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<float> 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<qfloat16> texture_ready_lut_data(OCIO_LUT3D_ENTRY_COUNT_WITH_ALPHA);
for (int i=0; i<OCIO_LUT3D_PIXEL_COUNT; i++) {
texture_ready_lut_data[i*kRGBAChannels+0] = lut_data[i*kRGBChannels+0];
texture_ready_lut_data[i*kRGBAChannels+1] = lut_data[i*kRGBChannels+1];
texture_ready_lut_data[i*kRGBAChannels+2] = lut_data[i*kRGBChannels+2];
texture_ready_lut_data[i*kRGBAChannels+3] = 1.0f;
}
// Create LUT texture
color_ctx.lut = CreateTexture(VideoParams(OCIO_LUT2D_EDGE_SIZE, OCIO_LUT2D_EDGE_SIZE, PixelFormat::PIX_FMT_RGBA32F),
texture_ready_lut_data.data());
// Create shader
QString frag_code;
frag_code.append(QStringLiteral("sampler2D texture;\n"
"sampler2D lut;\n"
"\n"
"vec3 LUTLookup(sampler2D lut3d, vec3 in_coord)\n"
"{\n"
" return texture2D(lut3d, vec2());\n"
"}\n"
"\n"));
// Correct code for our GLSL set up
QString ocio_code = color_processor->GetProcessor()->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
+2 -2
View File
@@ -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;
+47 -47
View File
@@ -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;i<kRGBAChannels;i++) {
data_[i] *= rhs;
@@ -261,7 +261,7 @@ const Color &Color::operator*=(const float &rhs)
return *this;
}
const Color &Color::operator/=(const float &rhs)
const Color &Color::operator/=(const double &rhs)
{
for (int i=0;i<kRGBAChannels;i++) {
data_[i] /= rhs;
@@ -284,14 +284,14 @@ Color Color::operator-(const Color &rhs) const
return c;
}
Color Color::operator*(const float &rhs) const
Color Color::operator*(const double &rhs) const
{
Color c(*this);
c *= rhs;
return c;
}
Color Color::operator/(const float &rhs) const
Color Color::operator/(const double &rhs) const
{
Color c(*this);
c /= rhs;
+28 -28
View File
@@ -30,7 +30,7 @@
OLIVE_NAMESPACE_ENTER
/**
* @brief High precision 32-bit float based RGBA color value
* @brief High precision 64-bit float based RGBA color value
*/
class Color
{
@@ -38,11 +38,11 @@ public:
Color()
{
for (int i=0;i<kRGBAChannels;i++) {
data_[i] = 0;
data_[i] = 0.0;
}
}
Color(const float& r, const float& g, const float& b, const float& a = 1.0f)
Color(const double& r, const double& g, const double& b, const double& a = 1.0)
{
data_[0] = r;
data_[1] = g;
@@ -59,30 +59,30 @@ public:
*
* Hue expects a value between 0.0 and 360.0. Saturation and Value expect a value between 0.0 and 1.0.
*/
static Color fromHsv(const float& h, const float& s, const float &v);
static Color fromHsv(const double& h, const double& s, const double &v);
const float& red() const {return data_[0];}
const float& green() const {return data_[1];}
const float& blue() const {return data_[2];}
const float& alpha() const {return data_[3];}
const double& red() const {return data_[0];}
const double& green() const {return data_[1];}
const double& blue() const {return data_[2];}
const double& alpha() const {return data_[3];}
void toHsv(float* hue, float* sat, float* val) const;
float hsv_hue() const;
float hsv_saturation() const;
float value() const;
void toHsv(double* hue, double* sat, double* val) const;
double hsv_hue() const;
double hsv_saturation() const;
double value() const;
void toHsl(float* hue, float* sat, float* lightness) const;
float hsl_hue() const;
float hsl_saturation() const;
float lightness() const;
void toHsl(double* hue, double* sat, double* lightness) const;
double hsl_hue() const;
double hsl_saturation() const;
double lightness() const;
void set_red(const float& red) {data_[0] = red;}
void set_green(const float& green) {data_[1] = green;}
void set_blue(const float& blue) {data_[2] = blue;}
void set_alpha(const float& alpha) {data_[3] = alpha;}
void set_red(const double& red) {data_[0] = red;}
void set_green(const double& green) {data_[1] = green;}
void set_blue(const double& blue) {data_[2] = blue;}
void set_alpha(const double& alpha) {data_[3] = alpha;}
float* data() {return data_;}
const float* data() const {return data_;}
double* data() {return data_;}
const double* data() const {return data_;}
void toData(char* data, const PixelFormat::Format& format) const;
@@ -92,22 +92,22 @@ public:
// Suuuuper rough luminance value mostly used for UI (determining whether to overlay with black
// or white text)
float GetRoughLuminance() const;
double GetRoughLuminance() const;
// Assignment math operators
const Color& operator+=(const Color& rhs);
const Color& operator-=(const Color& rhs);
const Color& operator*=(const float& rhs);
const Color& operator/=(const float& rhs);
const Color& operator*=(const double& rhs);
const Color& operator/=(const double& rhs);
// Binary math operators
Color operator+(const Color& rhs) const;
Color operator-(const Color& rhs) const;
Color operator*(const float& rhs) const;
Color operator/(const float& rhs) const;
Color operator*(const double& rhs) const;
Color operator/(const double& rhs) const;
private:
float data_[kRGBAChannels];
double data_[kRGBAChannels];
};
+1 -11
View File
@@ -302,7 +302,7 @@ QStringList ColorManager::ListAvailableColorspaces(OCIO::ConstConfigRcPtr config
return spaces;
}
void ColorManager::GetDefaultLumaCoefs(float *rgb) const
void ColorManager::GetDefaultLumaCoefs(double *rgb) const
{
config_->getDefaultLumaCoefs(rgb);
}
@@ -320,16 +320,6 @@ Color ColorManager::GetDefaultLumaCoefs() const
return c;
}
ColorManager::OCIOMethod ColorManager::GetOCIOMethodForMode(RenderMode::Mode mode)
{
return static_cast<OCIOMethod>(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;
+1 -10
View File
@@ -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:
+42 -13
View File
@@ -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<float*>(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)
+4 -1
View File
@@ -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_;
};
+1 -2
View File
@@ -21,11 +21,10 @@
#ifndef COLORTRANSFORM_H
#define COLORTRANSFORM_H
#include <OpenColorIO/OpenColorIO.h>
#include <QString>
#include "common/define.h"
#include "common/ocioutils.h"
OLIVE_NAMESPACE_ENTER
+22
View File
@@ -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()
+3
View File
@@ -26,6 +26,7 @@
#include <QOpenGLExtraFunctions>
#include <QString>
#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();
+6 -2
View File
@@ -585,7 +585,9 @@ void PreviewAutoCacher::TryRender()
watcher->SetTicket(RenderManager::instance()->RenderFrame(copied_viewer_node_,
color_manager_,
single_frame_render_->property("time").value<rational>(),
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));
}
}
+4 -3
View File
@@ -93,7 +93,7 @@ QByteArray RenderManager::Hash(const Node *n, const VideoParams &params, 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<RenderTicket>();
@@ -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
+2 -2
View File
@@ -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
+8 -2
View File
@@ -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<ColorManager>(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<ViewerOutput>(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";
}
}
+14
View File
@@ -1,6 +1,8 @@
#ifndef SHADERINFO_H
#define SHADERINFO_H
#include <QMatrix4x4>
#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 {