media node upgrades to reference pixel format

This commit is contained in:
itsmattkc
2019-08-29 12:30:42 +10:00
parent 7dc2290496
commit deff114241
21 changed files with 574 additions and 197 deletions
+107 -28
View File
@@ -34,8 +34,10 @@
// End test code
MediaInput::MediaInput() :
//ocio_shader_(nullptr),
decoder_(nullptr)
decoder_(nullptr),
color_service_(nullptr),
pipeline_(nullptr),
ocio_texture_(0)
{
footage_input_ = new NodeInput("footage_in");
footage_input_->add_data_input(NodeInput::kFootage);
@@ -72,9 +74,20 @@ QString MediaInput::Description()
void MediaInput::Release()
{
texture_.Destroy();
internal_tex_.Destroy();
decoder_ = nullptr;
color_service_ = nullptr;
pipeline_ = nullptr;
if (ocio_texture_ != 0) {
ocio_ctx_->functions()->glDeleteTextures(1, &ocio_texture_);
}
}
NodeInput *MediaInput::matrix_input()
{
return matrix_input_;
}
NodeOutput *MediaInput::texture_output()
@@ -89,6 +102,8 @@ void MediaInput::SetFootage(Footage *f)
QVariant MediaInput::Value(NodeOutput *output, const rational &time)
{
bool alpha_is_associated = false;
if (output == texture_output_) {
// Find the current Renderer instance
RenderInstance* renderer = RendererProcessor::CurrentInstance();
@@ -126,42 +141,106 @@ QVariant MediaInput::Value(NodeOutput *output, const rational &time)
return 0;
}
RenderTexturePtr texture = std::make_shared<RenderTexture>();
if (color_service_ == nullptr) {
// FIXME: Hardcoded values for texting
color_service_ = std::make_shared<ColorService>("srgb", OCIO::ROLE_SCENE_LINEAR);
}
texture->Create(renderer->context(),
// OpenColorIO v1's color transforms can be done on GPU, which improves performance but reduces accuracy. When
// online, we prefer accuracy over performance so we use the CPU path instead:
// NOTE: OCIO v2 boasts 1:1 results with the CPU and GPU path so this won't be necessary forever
if (renderer->mode() == olive::RenderMode::kOnline) {
// Convert to 32F, which is required for OpenColorIO's color transformation
frame = PixelService::ConvertPixelFormat(frame, olive::PIX_FMT_RGBA32F);
if (alpha_is_associated) {
// FIXME: Unassociate alpha here if associated
}
// Transform color to reference space
color_service_->ConvertFrame(frame);
if (alpha_is_associated) {
// FIXME: Reassociate alpha here
} else {
// FIXME: Associate alpha here
}
}
// We use an internal texture to bring the texture into GPU space before performing transformations
// Ensure the texture is the accurate to the frame
if (internal_tex_.width() != frame->width()
|| internal_tex_.height() != frame->height()
|| internal_tex_.format() != frame->format()) {
internal_tex_.Destroy();
}
// Create or upload the new data to the texture
if (!internal_tex_.IsCreated()) {
internal_tex_.Create(renderer->context(),
frame->width(),
frame->height(),
static_cast<olive::PixelFormat>(frame->format()),
frame->data());
} else {
internal_tex_.Upload(frame->data());
}
// Create new texture in reference space to send throughout the rest of the graph
RenderTexturePtr output_texture = std::make_shared<RenderTexture>();
output_texture->Create(renderer->context(),
renderer->width(),
renderer->height(),
static_cast<olive::PixelFormat>(frame->format()),
frame->data());
renderer->format(),
RenderTexture::kDoubleBuffer);
return QVariant::fromValue(texture);
// Using the transformation matrix, blit our internal texture (in frame format) to our output texture (in
// reference format)
/*renderer->buffer()->Upload(frame->data());
if (renderer->mode() == olive::RenderMode::kOffline) {
// For offline rendering, OCIO's GPU path is acceptable:
// NOTE: OCIO v2 boasts 1:1 results with the CPU and GPU path so this won't be necessary forever
texture_output_->set_value(renderer->buffer()->texture());*/
// Use an OCIO pipeline shader (which wraps in a default pipeline and will also handle alpha association)
if (pipeline_ == nullptr) {
/*pipeline_ = olive::ShaderGenerator::OCIOPipeline(renderer->context(),
ocio_texture_, // FIXME: A raw GLuint texture, should wrap this up
color_service_->GetProcessor(),
alpha_is_associated);
// Convert the frame to the Renderer format
// frame = PixelService::ConvertPixelFormat(frame, olive::PIX_FMT_RGBA16F);
// Used for cleanup later
ocio_ctx_ = renderer->context();*/
// Convert the frame to the Renderer color space
//color_service_.ConvertFrame(frame);
pipeline_ = olive::ShaderGenerator::DefaultPipeline();
}
} else if (pipeline_ == nullptr) {
// In online, the color transformation was performed on the CPU (see above), so we only need to blit
pipeline_ = olive::ShaderGenerator::DefaultPipeline();
}
// Upload this frame to the GPU
/*if (buffer_.IsCreated()) {
buffer_.Upload(frame->data());
} else {
buffer_.Create(QOpenGLContext::currentContext(),
static_cast<olive::PixelFormat>(frame->format()),
frame->width(),
frame->height(),
frame->data());
}*/
// Draw onto the output texture using the renderer's framebuffer
renderer->buffer()->Attach(output_texture);
renderer->buffer()->Bind();
// Draw according to matrix
// BLIT
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
//texture_output_->set_value(tex_buf_.texture());
// End test code
// Draw with the internal texture
internal_tex_.Bind();
// Use pipeline to blit using transformation matrix from input
QMatrix4x4 m;
olive::gl::Blit(pipeline_, false);
// Release everything
internal_tex_.Release();
renderer->buffer()->Detach();
renderer->buffer()->Release();
return QVariant::fromValue(output_texture);
}
return 0;
+10 -6
View File
@@ -26,11 +26,8 @@
#include "decoder/decoder.h"
#include "node/node.h"
#include "render/colorservice.h"
// FIXME: Test code only
#include "render/rendertexture.h"
#include "render/gl/shaderptr.h"
// End test code
#include "render/gl/shadergenerators.h"
/**
* @brief A node that imports an image
@@ -48,6 +45,8 @@ public:
virtual void Release() override;
NodeInput* matrix_input();
NodeOutput* texture_output();
void SetFootage(Footage* f);
@@ -62,11 +61,16 @@ private:
NodeOutput* texture_output_;
RenderTexture texture_;
RenderTexture internal_tex_;
DecoderPtr decoder_;
ColorService color_service_;
ColorServicePtr color_service_;
ShaderPtr pipeline_;
QOpenGLContext* ocio_ctx_;
GLuint ocio_texture_;
};