Merge branch 'master' into multicam

This commit is contained in:
itsmattkc
2022-09-25 16:39:03 -07:00
100 changed files with 2450 additions and 977 deletions
+4 -1
View File
@@ -26,10 +26,13 @@
namespace olive {
class AcceleratedJob {
class AcceleratedJob
{
public:
AcceleratedJob() = default;
virtual ~AcceleratedJob(){}
NodeValue Get(const QString& input) const
{
return value_map_.value(input);
+8 -7
View File
@@ -24,13 +24,16 @@
#include <QString>
#include <QVariant>
#include "node/value.h"
#include "render/job/acceleratedjob.h"
namespace olive {
class CacheJob
class CacheJob : public AcceleratedJob
{
public:
CacheJob() = default;
CacheJob(const QString &filename, const QVariant &fallback = QVariant())
CacheJob(const QString &filename, const NodeValue &fallback = NodeValue())
{
filename_ = filename;
}
@@ -38,18 +41,16 @@ public:
const QString &GetFilename() const { return filename_; }
void SetFilename(const QString &s) { filename_ = s; }
const QVariant &GetFallback() const { return fallback_; }
void SetFallback(const QVariant &val) { fallback_ = val; }
const NodeValue &GetFallback() const { return fallback_; }
void SetFallback(const NodeValue &val) { fallback_ = val; }
private:
QString filename_;
QVariant fallback_;
NodeValue fallback_;
};
}
Q_DECLARE_METATYPE(olive::CacheJob)
#endif // CACHEJOB_H
+16 -8
View File
@@ -24,7 +24,7 @@
#include <QMatrix4x4>
#include <QString>
#include "render/job/generatejob.h"
#include "acceleratedjob.h"
#include "render/alphaassoc.h"
#include "render/colorprocessor.h"
#include "render/texture.h"
@@ -33,18 +33,23 @@ namespace olive {
class Node;
class ColorTransformJob : public GenerateJob
class ColorTransformJob : public AcceleratedJob
{
public:
ColorTransformJob()
{
processor_ = nullptr;
input_texture_ = nullptr;
custom_shader_src_ = nullptr;
input_alpha_association_ = kAlphaNone;
clear_destination_ = true;
}
ColorTransformJob(const NodeValueRow &row) :
ColorTransformJob()
{
Insert(row);
}
QString id() const
{
if (id_.isEmpty()) {
@@ -56,8 +61,13 @@ public:
void SetOverrideID(const QString &id) { id_ = id; }
TexturePtr GetInputTexture() const { return input_texture_; }
void SetInputTexture(TexturePtr tex) { input_texture_ = tex; }
const NodeValue &GetInputTexture() const { return input_texture_; }
void SetInputTexture(const NodeValue &tex) { input_texture_ = tex; }
void SetInputTexture(TexturePtr tex)
{
Q_ASSERT(!tex->IsDummy());
input_texture_ = NodeValue(NodeValue::kTexture, tex);
}
ColorProcessorPtr GetColorProcessor() const { return processor_; }
void SetColorProcessor(ColorProcessorPtr p) { processor_ = p; }
@@ -89,7 +99,7 @@ private:
ColorProcessorPtr processor_;
QString id_;
TexturePtr input_texture_;
NodeValue input_texture_;
const Node *custom_shader_src_;
QString custom_shader_id_;
@@ -108,6 +118,4 @@ private:
}
Q_DECLARE_METATYPE(olive::ColorTransformJob)
#endif // COLORTRANSFORMJOB_H
+7 -2
View File
@@ -25,7 +25,7 @@
namespace olive {
class FootageJob
class FootageJob : public AcceleratedJob
{
public:
FootageJob() :
@@ -33,7 +33,8 @@ public:
{
}
FootageJob(const QString& decoder, const QString& filename, Track::Type type, const rational& length) :
FootageJob(const TimeRange &time, const QString& decoder, const QString& filename, Track::Type type, const rational& length) :
time_(time),
decoder_(decoder),
filename_(filename),
type_(type),
@@ -96,7 +97,11 @@ public:
length_ = length;
}
const TimeRange &time() const { return time_; }
private:
TimeRange time_;
QString decoder_;
QString filename_;
+7 -18
View File
@@ -22,33 +22,22 @@
#define GENERATEJOB_H
#include "acceleratedjob.h"
#include "render/videoparams.h"
#include "codec/frame.h"
namespace olive {
class GenerateJob : public AcceleratedJob {
class GenerateJob : public AcceleratedJob
{
public:
GenerateJob()
GenerateJob() = default;
GenerateJob(const NodeValueRow &row) :
GenerateJob()
{
requested_format_ = VideoParams::kFormatInvalid;
Insert(row);
}
VideoParams::Format GetRequestedFormat() const { return requested_format_; }
void SetRequestedFormat(VideoParams::Format f) { requested_format_ = f; }
const QString &GetColorspace() const { return colorspace_; }
void SetColorspace(const QString &s) { colorspace_ = s; }
private:
VideoParams::Format requested_format_;
QString colorspace_;
};
}
Q_DECLARE_METATYPE(olive::GenerateJob)
#endif // GENERATEJOB_H
+11 -3
View File
@@ -23,23 +23,27 @@
#include "acceleratedjob.h"
#include "codec/samplebuffer.h"
#include "common/timerange.h"
namespace olive {
class SampleJob : public AcceleratedJob {
class SampleJob : public AcceleratedJob
{
public:
SampleJob()
{
}
SampleJob(const NodeValue& value)
SampleJob(const TimeRange &time, const NodeValue& value)
{
samples_ = value.toSamples();
time_ = time;
}
SampleJob(const QString& from, const NodeValueRow& row)
SampleJob(const TimeRange &time, const QString& from, const NodeValueRow& row)
{
samples_ = row[from].toSamples();
time_ = time;
}
const SampleBuffer &samples() const
@@ -52,9 +56,13 @@ public:
return samples_.is_allocated();
}
const TimeRange &time() const { return time_; }
private:
SampleBuffer samples_;
TimeRange time_;
};
}
+9 -11
View File
@@ -24,19 +24,24 @@
#include <QMatrix4x4>
#include <QVector>
#include "generatejob.h"
#include "render/colorprocessor.h"
#include "acceleratedjob.h"
#include "render/texture.h"
namespace olive {
class ShaderJob : public GenerateJob {
class ShaderJob : public AcceleratedJob
{
public:
ShaderJob()
{
iterations_ = 1;
iterative_input_ = nullptr;
will_change_image_size_ = true;
}
ShaderJob(const NodeValueRow &row) :
ShaderJob()
{
Insert(row);
}
const QString& GetShaderID() const
@@ -100,9 +105,6 @@ public:
return vertex_overrides_;
}
bool GetWillChangeImageSize() const { return will_change_image_size_; }
void SetWillChangeImageSize(bool e) { will_change_image_size_ = e; }
private:
QString shader_id_;
@@ -114,12 +116,8 @@ private:
QVector<float> vertex_overrides_;
bool will_change_image_size_;
};
}
Q_DECLARE_METATYPE(olive::ShaderJob)
#endif // SHADERJOB_H
+2 -1
View File
@@ -364,7 +364,7 @@ void OpenGLRenderer::Flush()
{
GL_PREAMBLE;
functions_->glFlush();
functions_->glFinish();
}
Color OpenGLRenderer::GetPixelFromTexture(Texture *texture, const QPointF &pt)
@@ -415,6 +415,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
// This variable is used in the shader, let's set it
const NodeValue& value = it.value();
// Arrays are not currently supported in this system
if (value.array()) {
continue;
}
+16 -4
View File
@@ -68,7 +68,16 @@ void PlaybackCache::LoadState()
{
QDir cache_dir = GetThisCacheDirectory();
QFile f(cache_dir.filePath(QStringLiteral("state")));
if (f.open(QFile::ReadOnly)) {
if (!f.exists()) {
// No state exists, assume nothing valid
validated_.clear();
passthroughs_.clear();
return;
}
qint64 file_time = f.fileTime(QFileDevice::FileModificationTime).toMSecsSinceEpoch();
if (file_time > last_loaded_state_ && f.open(QFile::ReadOnly)) {
QDataStream s(&f);
uint32_t version;
@@ -81,7 +90,6 @@ void PlaybackCache::LoadState()
{
int valid_count, pass_count;
validated_.clear();
s >> valid_count;
for (int i=0; i<valid_count; i++) {
int in_num, in_den, out_num, out_den;
@@ -94,7 +102,6 @@ void PlaybackCache::LoadState()
validated_.insert(TimeRange(rational(in_num, in_den), rational(out_num, out_den)));
}
passthroughs_.clear();
s >> pass_count;
for (int i=0; i<pass_count; i++) {
QUuid id;
@@ -116,6 +123,8 @@ void PlaybackCache::LoadState()
}
f.close();
last_loaded_state_ = file_time;
}
}
@@ -161,6 +170,8 @@ void PlaybackCache::SaveState()
}
f.close();
last_loaded_state_ = f.fileTime(QFileDevice::FileModificationTime).toMSecsSinceEpoch();
}
}
}
@@ -236,7 +247,8 @@ Project *PlaybackCache::GetProject() const
PlaybackCache::PlaybackCache(QObject *parent) :
QObject(parent),
saving_enabled_(true)
saving_enabled_(true),
last_loaded_state_(0)
{
uuid_ = QUuid::createUuid();
}
+2
View File
@@ -132,6 +132,8 @@ private:
QVector<Passthrough> passthroughs_;
qint64 last_loaded_state_;
};
}
+1 -1
View File
@@ -292,7 +292,7 @@ void Renderer::BlitColorManaged(const ColorTransformJob &color_job, Texture *des
}
ShaderJob job;
job.Insert(QStringLiteral("ove_maintex"), NodeValue(NodeValue::kTexture, QVariant::fromValue(color_job.GetInputTexture())));
job.Insert(QStringLiteral("ove_maintex"), color_job.GetInputTexture());
job.Insert(QStringLiteral("ove_mvpmat"), NodeValue(NodeValue::kMatrix, color_job.GetTransformMatrix()));
job.Insert(QStringLiteral("ove_cropmatrix"), NodeValue(NodeValue::kMatrix, color_job.GetCropMatrix().inverted()));
job.Insert(QStringLiteral("ove_maintex_alpha"), NodeValue(NodeValue::kInt, int(color_job.GetInputAlphaAssociation())));
+32 -23
View File
@@ -54,7 +54,7 @@ TexturePtr RenderProcessor::GenerateTexture(const rational &time, const rational
NodeValue tex_val = table.Get(NodeValue::kTexture);
ResolveJobs(tex_val, range);
ResolveJobs(tex_val);
return tex_val.toTexture();
}
@@ -226,7 +226,7 @@ void RenderProcessor::Run()
NodeValue sample_val = table.Get(NodeValue::kSamples);
ResolveJobs(sample_val, time);
ResolveJobs(sample_val);
SampleBuffer samples = sample_val.toSamples();
if (samples.is_allocated()) {
@@ -300,7 +300,7 @@ void RenderProcessor::Process(RenderTicketPtr ticket, Renderer *render_ctx, Deco
p.Run();
}
void RenderProcessor::ProcessVideoFootage(TexturePtr destination, const FootageJob &stream, const rational &input_time)
void RenderProcessor::ProcessVideoFootage(TexturePtr destination, const FootageJob *stream, const rational &input_time)
{
if (ticket_->property("type").value<RenderManager::TicketType>() != RenderManager::kTypeVideo) {
// Video cannot contribute to audio, so we do nothing here
@@ -310,7 +310,7 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, const FootageJ
// Check the still frame cache. On large frames such as high resolution still images, uploading
// and color managing them for every frame is a waste of time, so we implement a small cache here
// to optimize such a situation
VideoParams stream_data = stream.video_params();
VideoParams stream_data = stream->video_params();
ColorManager* color_manager = Node::ValueToPtr<ColorManager>(ticket_->property("colormanager"));
@@ -321,9 +321,9 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, const FootageJ
qWarning() << "HAVEN'T GOTTEN DEFAULT INPUT COLORSPACE";
}
Decoder::CodecStream default_codec_stream(stream.filename(), stream_data.stream_index(), GetCurrentBlock());
Decoder::CodecStream default_codec_stream(stream->filename(), stream_data.stream_index(), GetCurrentBlock());
QString decoder_id = stream.decoder();
QString decoder_id = stream->decoder();
DecoderPtr decoder = nullptr;
@@ -341,7 +341,7 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, const FootageJ
QString frame_filename;
int64_t frame_number = stream_data.get_time_in_timebase_units(input_time);
frame_filename = Decoder::TransformImageSequenceFileName(stream.filename(), frame_number);
frame_filename = Decoder::TransformImageSequenceFileName(stream->filename(), frame_number);
// Decoder will close automatically since it's a stream_ptr
decoder->Open(Decoder::CodecStream(frame_filename, stream_data.stream_index(), GetCurrentBlock()));
@@ -352,11 +352,11 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, const FootageJ
if (decoder && render_ctx_) {
Decoder::RetrieveVideoParams p;
p.divider = stream.video_params().divider();
p.divider = stream->video_params().divider();
p.maximum_format = destination->format();
if (!IsCancelled()) {
VideoParams tex_params = stream.video_params();
VideoParams tex_params = stream->video_params();
if (tex_params.is_valid()) {
TexturePtr unmanaged_texture;
@@ -397,16 +397,16 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination, const FootageJ
}
}
void RenderProcessor::ProcessAudioFootage(SampleBuffer &destination, const FootageJob &stream, const TimeRange &input_time)
void RenderProcessor::ProcessAudioFootage(SampleBuffer &destination, const FootageJob *stream, const TimeRange &input_time)
{
DecoderPtr decoder = ResolveDecoderFromInput(stream.decoder(), Decoder::CodecStream(stream.filename(), stream.audio_params().stream_index(), nullptr));
DecoderPtr decoder = ResolveDecoderFromInput(stream->decoder(), Decoder::CodecStream(stream->filename(), stream->audio_params().stream_index(), nullptr));
if (decoder) {
const AudioParams& audio_params = GetCacheAudioParams();
Decoder::RetrieveAudioStatus status = decoder->RetrieveAudio(destination,
input_time, audio_params,
stream.cache_path(),
stream->cache_path(),
loop_mode(),
static_cast<RenderMode::Mode>(ticket_->property("mode").toInt()));
@@ -416,13 +416,13 @@ void RenderProcessor::ProcessAudioFootage(SampleBuffer &destination, const Foota
}
}
void RenderProcessor::ProcessShader(TexturePtr destination, const Node *node, const TimeRange &range, const ShaderJob &job)
void RenderProcessor::ProcessShader(TexturePtr destination, const Node *node, const ShaderJob *job)
{
if (!render_ctx_) {
return;
}
QString full_shader_id = QStringLiteral("%1:%2").arg(node->id(), job.GetShaderID());
QString full_shader_id = QStringLiteral("%1:%2").arg(node->id(), job->GetShaderID());
QMutexLocker locker(shader_cache_->mutex());
@@ -430,16 +430,20 @@ void RenderProcessor::ProcessShader(TexturePtr destination, const Node *node, co
if (shader.isNull()) {
// Since we have shader code, compile it now
shader = render_ctx_->CreateNativeShader(node->GetShaderCode(job.GetShaderID()));
shader = render_ctx_->CreateNativeShader(node->GetShaderCode(job->GetShaderID()));
if (shader.isNull()) {
// Couldn't find or build the shader required
return;
}
shader_cache_->insert(full_shader_id, shader);
}
locker.unlock();
// Run shader
render_ctx_->BlitToTexture(shader, job, destination.get());
render_ctx_->BlitToTexture(shader, *job, destination.get());
}
void RenderProcessor::ProcessSamples(SampleBuffer &destination, const Node *node, const TimeRange &range, const SampleJob &job)
@@ -473,16 +477,16 @@ void RenderProcessor::ProcessSamples(SampleBuffer &destination, const Node *node
}
}
void RenderProcessor::ProcessColorTransform(TexturePtr destination, const Node *node, const ColorTransformJob &job)
void RenderProcessor::ProcessColorTransform(TexturePtr destination, const Node *node, const ColorTransformJob *job)
{
if (!render_ctx_) {
return;
}
render_ctx_->BlitColorManaged(job, destination.get());
render_ctx_->BlitColorManaged(*job, destination.get());
}
void RenderProcessor::ProcessFrameGeneration(TexturePtr destination, const Node *node, const GenerateJob &job)
void RenderProcessor::ProcessFrameGeneration(TexturePtr destination, const Node *node, const GenerateJob *job)
{
if (!render_ctx_) {
return;
@@ -493,14 +497,14 @@ void RenderProcessor::ProcessFrameGeneration(TexturePtr destination, const Node
frame->set_video_params(destination->params());
frame->allocate();
node->GenerateFrame(frame, job);
node->GenerateFrame(frame, *job);
destination->Upload(frame->data(), frame->linesize_pixels());
}
TexturePtr RenderProcessor::ProcessVideoCacheJob(const CacheJob &val)
TexturePtr RenderProcessor::ProcessVideoCacheJob(const CacheJob *val)
{
FramePtr frame = FrameHashCache::LoadCacheFrame(val.GetFilename());
FramePtr frame = FrameHashCache::LoadCacheFrame(val->GetFilename());
if (frame) {
TexturePtr tex = CreateTexture(frame->video_params());
if (tex) {
@@ -509,7 +513,7 @@ TexturePtr RenderProcessor::ProcessVideoCacheJob(const CacheJob &val)
}
} else {
QStringList s = ticket_->property("badcache").toStringList();
s.append(val.GetFilename());
s.append(val->GetFilename());
ticket_->setProperty("badcache", s);
}
@@ -543,4 +547,9 @@ void RenderProcessor::ConvertToReferenceSpace(TexturePtr destination, TexturePtr
render_ctx_->BlitColorManaged(ctj, destination.get());
}
bool RenderProcessor::UseCache() const
{
return static_cast<RenderMode::Mode>(ticket_->property("mode").toInt()) == RenderMode::kOffline;
}
}
+8 -6
View File
@@ -42,19 +42,19 @@ public:
};
protected:
virtual void ProcessVideoFootage(TexturePtr destination, const FootageJob &stream, const rational &input_time) override;
virtual void ProcessVideoFootage(TexturePtr destination, const FootageJob *stream, const rational &input_time) override;
virtual void ProcessAudioFootage(SampleBuffer &destination, const FootageJob &stream, const TimeRange &input_time) override;
virtual void ProcessAudioFootage(SampleBuffer &destination, const FootageJob *stream, const TimeRange &input_time) override;
virtual void ProcessShader(TexturePtr destination, const Node *node, const TimeRange &range, const ShaderJob& job) override;
virtual void ProcessShader(TexturePtr destination, const Node *node, const ShaderJob *job) override;
virtual void ProcessSamples(SampleBuffer &destination, const Node *node, const TimeRange &range, const SampleJob &job) override;
virtual void ProcessColorTransform(TexturePtr destination, const Node *node, const ColorTransformJob& job) override;
virtual void ProcessColorTransform(TexturePtr destination, const Node *node, const ColorTransformJob *job) override;
virtual void ProcessFrameGeneration(TexturePtr destination, const Node *node, const GenerateJob& job) override;
virtual void ProcessFrameGeneration(TexturePtr destination, const Node *node, const GenerateJob *job) override;
virtual TexturePtr ProcessVideoCacheJob(const CacheJob &val) override;
virtual TexturePtr ProcessVideoCacheJob(const CacheJob *val) override;
virtual TexturePtr CreateTexture(const VideoParams &p) override;
@@ -65,6 +65,8 @@ protected:
virtual void ConvertToReferenceSpace(TexturePtr destination, TexturePtr source, const QString &input_cs) override;
virtual bool UseCache() const override;
private:
RenderProcessor(RenderTicketPtr ticket, Renderer* render_ctx, DecoderCache* decoder_cache, ShaderCache* shader_cache);
+4
View File
@@ -31,6 +31,10 @@ Texture::~Texture()
if (renderer_) {
renderer_->DestroyTexture(this);
}
if (job_) {
delete job_;
}
}
void Texture::Upload(void *data, int linesize)
+37 -4
View File
@@ -27,8 +27,12 @@
namespace olive {
class AcceleratedJob;
class Renderer;
class Texture;
using TexturePtr = std::shared_ptr<Texture>;
class Texture
{
public:
@@ -45,17 +49,26 @@ public:
*/
Texture(const VideoParams& param) :
renderer_(nullptr),
params_(param)
params_(param),
job_(nullptr)
{
}
template <typename T>
Texture(const VideoParams &p, const T &j) :
Texture(p)
{
job_ = new T(j);
}
/**
* @brief Construct a real texture linked to a renderer backend
*/
Texture(Renderer* renderer, const QVariant& native, const VideoParams& param) :
renderer_(renderer),
params_(param),
id_(native)
id_(native),
job_(nullptr)
{
}
@@ -71,6 +84,18 @@ public:
return params_;
}
template <typename T>
static TexturePtr Job(const VideoParams &p, const T &j)
{
return std::make_shared<Texture>(p, j);
}
template <typename T>
TexturePtr toJob(const T &job)
{
return Texture::Job(params_, job);
}
void Upload(void* data, int linesize);
void Download(void* data, int linesize);
@@ -90,6 +115,11 @@ public:
return params_.effective_height();
}
QVector2D virtual_resolution() const
{
return QVector2D(params_.square_pixel_width(), params_.height());
}
VideoParams::Format format() const
{
return params_.format();
@@ -115,6 +145,9 @@ public:
return renderer_;
}
bool IsJob() const { return job_; }
AcceleratedJob *job() const { return job_; }
private:
Renderer* renderer_;
@@ -122,9 +155,9 @@ private:
QVariant id_;
};
AcceleratedJob *job_;
using TexturePtr = std::shared_ptr<Texture>;
};
}
+10
View File
@@ -107,6 +107,16 @@ public:
return par_width_;
}
QVector2D resolution() const
{
return QVector2D(width_, height_);
}
QVector2D square_resolution() const
{
return QVector2D(par_width_, height_);
}
int height() const
{
return height_;