style: unify identifier naming per updated conventions

Automated with clang-tidy readability-identifier-naming (config added to
.clang-tidy) plus scripted passes, per the updated rules now documented
in CONTRIBUTING.md:

- types (class/struct/enum/alias/template params): PascalCase
- functions, variables, members: snake_case (incl. rational -> Rational)
- private/protected members: trailing underscore; static member
  variables likewise (instance_, available_themes_)
- constants and enum values: snake_case (kLinear -> k_linear,
  F32P -> f32p); ALL_CAPS reserved for macros
- macros: OAK_ prefix (OLIVE_ADD_TEST/OLIVE_ASSERT/OLIVE_CONFIG ->
  OAK_ADD_TEST/OAK_ASSERT/OAK_CONFIG, GL_PREAMBLE -> OAK_GL_PREAMBLE,
  include guards -> OAK_*)
- file names: all lowercase (Current/Plugin/OliveHost/OliveClip/
  OlivePluginInstance -> current/plugin/olivehost/oliveclip/
  oliveplugininstance)
- getters share the member name sans underscore, setters set_foo()
- Qt and third-party (OpenFX) virtual overrides and framework callbacks
  keep their original names (exempt in .clang-tidy)

Manual follow-ups required where automation could not reach:
- string-based QMetaObject/SIGNAL/SLOT references updated to renamed
  methods (AddTask, CreatedFile, DeleteSpecificFile, moveSelectionUp, ...)
- macro bodies referencing renamed methods (OLIVE_CONFIG,
  NODE_DEFAULT_DESTRUCTOR, MANAGEDDISPLAYWIDGET_*)
- self-shadowing locals renamed where signals/methods became same-named
  (size_changed, worker_count, selected_items, import param, filters)
- third_party OFX member/namespace usages restored (OFX::Host::*,
  _created, _clipPrefsDirty, createInstance, clearPersistentMessage)
- STL protocol aliases restored (const_iterator) with .clang-tidy
  ignore rules; qHash overloads restored

Full build and test suite pass: ctest 4/4, ~1960 gtest cases green.
This commit is contained in:
2026-07-19 16:10:54 +08:00
parent cb1718a103
commit bb40b4923e
1014 changed files with 44257 additions and 44220 deletions
+4 -4
View File
@@ -19,14 +19,14 @@
***/
#ifndef ALPHAASSOC_H
#define ALPHAASSOC_H
#ifndef OAK_ALPHAASSOC_H
#define OAK_ALPHAASSOC_H
namespace olive
{
enum AlphaAssociated { kAlphaNone, kAlphaUnassociated, kAlphaAssociated };
enum AlphaAssociated { k_alpha_none, k_alpha_unassociated, k_alpha_associated };
}
#endif // ALPHAASSOC_H
#endif // OAK_ALPHAASSOC_H
+18 -18
View File
@@ -32,7 +32,7 @@
namespace olive
{
const qint64 AudioPlaybackCache::kDefaultSegmentSizePerChannel =
const qint64 AudioPlaybackCache::k_default_segment_size_per_channel =
10 * 1024 * 1024;
AudioPlaybackCache::AudioPlaybackCache(QObject *parent)
@@ -44,7 +44,7 @@ AudioPlaybackCache::~AudioPlaybackCache()
{
}
void AudioPlaybackCache::SetParameters(const AudioParams &params)
void AudioPlaybackCache::set_parameters(const AudioParams &params)
{
if (params_ == params) {
return;
@@ -53,29 +53,29 @@ void AudioPlaybackCache::SetParameters(const AudioParams &params)
params_ = params;
}
void AudioPlaybackCache::WritePCM(const TimeRange &range,
void AudioPlaybackCache::write_pcm(const TimeRange &range,
const TimeRangeList &valid_ranges,
const SampleBuffer &samples)
{
for (const TimeRange &r : valid_ranges) {
if (WritePartOfSampleBuffer(samples, r.in(), r.in() - range.in(),
if (write_part_of_sample_buffer(samples, r.in(), r.in() - range.in(),
r.length())) {
Validate(r);
validate(r);
}
}
}
void AudioPlaybackCache::WriteSilence(const TimeRange &range)
void AudioPlaybackCache::write_silence(const TimeRange &range)
{
// WritePCM will automatically fill non-existent bytes with silence, so we just have to send
// it an empty sample buffer
WritePCM(range, { range }, SampleBuffer());
write_pcm(range, { range }, SampleBuffer());
}
bool AudioPlaybackCache::WritePartOfSampleBuffer(const SampleBuffer &samples,
const rational &write_start,
const rational &buffer_start,
const rational &length)
bool AudioPlaybackCache::write_part_of_sample_buffer(const SampleBuffer &samples,
const Rational &write_start,
const Rational &buffer_start,
const Rational &length)
{
int64_t length_in_bytes = params_.time_to_bytes_per_channel(length);
@@ -94,9 +94,9 @@ bool AudioPlaybackCache::WritePartOfSampleBuffer(const SampleBuffer &samples,
bool success = true;
while (current_cache_offset != end_cache_offset) {
int64_t segment = current_cache_offset / kDefaultSegmentSizePerChannel;
int64_t segment_start = segment * kDefaultSegmentSizePerChannel;
int64_t segment_end = segment_start + kDefaultSegmentSizePerChannel;
int64_t segment = current_cache_offset / k_default_segment_size_per_channel;
int64_t segment_start = segment * k_default_segment_size_per_channel;
int64_t segment_end = segment_start + k_default_segment_size_per_channel;
int64_t offset_in_segment = current_cache_offset - segment_start;
// Never write past the end of the requested range
@@ -111,9 +111,9 @@ bool AudioPlaybackCache::WritePartOfSampleBuffer(const SampleBuffer &samples,
}
for (int channel = 0; channel < params_.channel_count(); channel++) {
QString filename = GetSegmentFilename(segment, channel);
QString filename = get_segment_filename(segment, channel);
if (!FileFunctions::DirectoryIsValid(QFileInfo(filename).dir())) {
if (!FileFunctions::directory_is_valid(QFileInfo(filename).dir())) {
success = false;
break;
}
@@ -147,10 +147,10 @@ bool AudioPlaybackCache::WritePartOfSampleBuffer(const SampleBuffer &samples,
return success;
}
QString AudioPlaybackCache::GetSegmentFilename(qint64 segment_index,
QString AudioPlaybackCache::get_segment_filename(qint64 segment_index,
int channel)
{
return GetThisCacheDirectory().filePath(QStringLiteral("%1.%2").arg(
return get_this_cache_directory().filePath(QStringLiteral("%1.%2").arg(
QString::number(segment_index), QString::number(channel)));
}
+13 -13
View File
@@ -19,8 +19,8 @@
***/
#ifndef AUDIOPLAYBACKCACHE_H
#define AUDIOPLAYBACKCACHE_H
#ifndef OAK_AUDIOPLAYBACKCACHE_H
#define OAK_AUDIOPLAYBACKCACHE_H
#include "audio/audiovisualwaveform.h"
#include "render/playbackcache.h"
@@ -58,31 +58,31 @@ public:
virtual ~AudioPlaybackCache() override;
AudioParams GetParameters()
AudioParams get_parameters()
{
return params_;
}
void SetParameters(const AudioParams &params);
void set_parameters(const AudioParams &params);
void WritePCM(const TimeRange &range, const TimeRangeList &valid_ranges,
void write_pcm(const TimeRange &range, const TimeRangeList &valid_ranges,
const SampleBuffer &samples);
void WriteSilence(const TimeRange &range);
void write_silence(const TimeRange &range);
private:
bool WritePartOfSampleBuffer(const SampleBuffer &samples,
const rational &write_start,
const rational &buffer_start,
const rational &length);
bool write_part_of_sample_buffer(const SampleBuffer &samples,
const Rational &write_start,
const Rational &buffer_start,
const Rational &length);
QString GetSegmentFilename(qint64 segment_index, int channel);
QString get_segment_filename(qint64 segment_index, int channel);
static const qint64 kDefaultSegmentSizePerChannel;
static const qint64 k_default_segment_size_per_channel;
AudioParams params_;
};
}
#endif // AUDIOPLAYBACKCACHE_H
#endif // OAK_AUDIOPLAYBACKCACHE_H
+22 -22
View File
@@ -32,51 +32,51 @@ AudioWaveformCache::AudioWaveformCache(QObject *parent)
waveforms_ = std::make_shared<AudioVisualWaveform>();
}
void AudioWaveformCache::WriteWaveform(const TimeRange &range,
void AudioWaveformCache::write_waveform(const TimeRange &range,
const TimeRangeList &valid_ranges,
const AudioVisualWaveform *waveform)
{
// Write each valid range to the segments
foreach (const TimeRange &r, valid_ranges) {
if (waveform) {
waveforms_->OverwriteSums(*waveform, r.in(), r.in() - range.in(),
waveforms_->overwrite_sums(*waveform, r.in(), r.in() - range.in(),
r.length());
}
Validate(r);
validate(r);
}
}
void DrawSubRect(QPainter *painter, const QRect &rect, const double &scale,
void draw_sub_rect(QPainter *painter, const QRect &rect, const double &scale,
const TimeRange &wave_range,
const AudioVisualWaveform &waveform, const TimeRange &subrange)
{
// Find start time of passthrough
TimeRange intersect = wave_range.Intersected(subrange);
TimeRange intersect = wave_range.intersected(subrange);
// Create new rect that starts at the offset of pass_start from start_time
// Set rect width to either length of passthrough or until the end
QRect pass_rect(
rect.x() + (intersect.in() - wave_range.in()).toDouble() * scale,
rect.y(), intersect.length().toDouble() * scale, rect.height());
rect.x() + (intersect.in() - wave_range.in()).to_double() * scale,
rect.y(), intersect.length().to_double() * scale, rect.height());
// Draw waveform with this info
AudioVisualWaveform::DrawWaveform(painter, pass_rect, scale, waveform,
AudioVisualWaveform::draw_waveform(painter, pass_rect, scale, waveform,
intersect.in());
}
void AudioWaveformCache::Draw(QPainter *painter, const QRect &rect,
const double &scale,
const rational &start_time) const
const Rational &start_time) const
{
if (!passthroughs_.empty()) {
TimeRange wave_range(start_time,
start_time +
rational::fromDouble(rect.width() / scale));
Rational::from_double(rect.width() / scale));
TimeRangeList draw_range = { wave_range };
for (const WaveformPassthrough &p : passthroughs_) {
if (draw_range.OverlapsWith(p, true, false)) {
DrawSubRect(painter, rect, scale, wave_range, *p.waveform, p);
if (draw_range.overlaps_with(p, true, false)) {
draw_sub_rect(painter, rect, scale, wave_range, *p.waveform, p);
// Remove this range
draw_range.remove(p);
@@ -84,31 +84,31 @@ void AudioWaveformCache::Draw(QPainter *painter, const QRect &rect,
}
for (const TimeRange &r : draw_range) {
DrawSubRect(painter, rect, scale, wave_range, *waveforms_, r);
draw_sub_rect(painter, rect, scale, wave_range, *waveforms_, r);
}
} else {
AudioVisualWaveform::DrawWaveform(painter, rect, scale, *waveforms_,
AudioVisualWaveform::draw_waveform(painter, rect, scale, *waveforms_,
start_time);
}
}
AudioVisualWaveform::Sample
AudioWaveformCache::GetSummaryFromTime(const rational &start,
const rational &length) const
AudioWaveformCache::get_summary_from_time(const Rational &start,
const Rational &length) const
{
return waveforms_->GetSummaryFromTime(start, length);
return waveforms_->get_summary_from_time(start, length);
}
rational AudioWaveformCache::length() const
Rational AudioWaveformCache::length() const
{
return waveforms_->length();
}
void AudioWaveformCache::SetPassthrough(PlaybackCache *cache)
void AudioWaveformCache::set_passthrough(PlaybackCache *cache)
{
AudioWaveformCache *c = static_cast<AudioWaveformCache *>(cache);
for (const TimeRange &r : c->GetValidatedRanges()) {
for (const TimeRange &r : c->get_validated_ranges()) {
WaveformPassthrough t = r;
t.waveform = c->waveforms_;
passthroughs_.push_back(t);
@@ -116,8 +116,8 @@ void AudioWaveformCache::SetPassthrough(PlaybackCache *cache)
passthroughs_.insert(passthroughs_.end(), c->passthroughs_.begin(),
c->passthroughs_.end());
SetParameters(c->GetParameters());
SetSavingEnabled(c->IsSavingEnabled());
set_parameters(c->get_parameters());
set_saving_enabled(c->is_saving_enabled());
}
void AudioWaveformCache::InvalidateEvent(const TimeRange &range)
+10 -10
View File
@@ -19,8 +19,8 @@
***/
#ifndef AUDIOWAVEFORMCACHE_H
#define AUDIOWAVEFORMCACHE_H
#ifndef OAK_AUDIOWAVEFORMCACHE_H
#define OAK_AUDIOWAVEFORMCACHE_H
#include "audio/audiovisualwaveform.h"
#include "playbackcache.h"
@@ -33,29 +33,29 @@ class AudioWaveformCache : public PlaybackCache {
public:
AudioWaveformCache(QObject *parent = nullptr);
void WriteWaveform(const TimeRange &range,
void write_waveform(const TimeRange &range,
const TimeRangeList &valid_ranges,
const AudioVisualWaveform *waveform);
const AudioParams &GetParameters() const
const AudioParams &get_parameters() const
{
return params_;
}
void SetParameters(const AudioParams &p)
void set_parameters(const AudioParams &p)
{
params_ = p;
waveforms_->set_channel_count(p.channel_count());
}
void Draw(QPainter *painter, const QRect &rect, const double &scale,
const rational &start_time) const;
const Rational &start_time) const;
AudioVisualWaveform::Sample
GetSummaryFromTime(const rational &start, const rational &length) const;
get_summary_from_time(const Rational &start, const Rational &length) const;
rational length() const;
Rational length() const;
virtual void SetPassthrough(PlaybackCache *cache) override;
virtual void set_passthrough(PlaybackCache *cache) override;
protected:
virtual void InvalidateEvent(const TimeRange &range) override;
@@ -82,4 +82,4 @@ private:
}
#endif // AUDIOWAVEFORMCACHE_H
#endif // OAK_AUDIOWAVEFORMCACHE_H
+37 -37
View File
@@ -21,8 +21,8 @@ DynamicRenderer::DynamicRenderer(const QString &backend, QObject *parent)
// resources, destroy the opaque backend object, then unload the shared library.
DynamicRenderer::~DynamicRenderer()
{
Destroy();
PostDestroy();
destroy();
post_destroy();
if (handle_ && destroy_) {
destroy_(handle_);
handle_ = nullptr;
@@ -35,7 +35,7 @@ DynamicRenderer::~DynamicRenderer()
// Builds the private backend library path for the current platform.
// The search is intentionally restricted to Oak-controlled directories so a
// system libGL/libvulkan loader is never mistaken for an Oak render backend.
QString DynamicRenderer::LibraryFilename() const
QString DynamicRenderer::library_filename() const
{
QString base;
if (backend_ == QStringLiteral("opengl")) {
@@ -78,20 +78,20 @@ QString DynamicRenderer::LibraryFilename() const
// Loads the selected backend, resolves its C ABI table, creates the opaque
// backend object, and optionally falls back from Vulkan to OpenGL when runtime
// availability checks fail.
bool DynamicRenderer::Load()
bool DynamicRenderer::load()
{
if (handle_) {
return true;
}
library_.setFileName(LibraryFilename());
library_.setFileName(library_filename());
if (!library_.load()) {
if (backend_ == QStringLiteral("vulkan")) {
qWarning()
<< "Failed to load Vulkan render backend" << library_.fileName()
<< library_.errorString() << "falling back to OpenGL backend";
backend_ = QStringLiteral("opengl");
library_.setFileName(LibraryFilename());
library_.setFileName(library_filename());
}
if (!library_.load()) {
@@ -101,7 +101,7 @@ bool DynamicRenderer::Load()
}
}
if (!ResolveFunctions()) {
if (!resolve_functions()) {
qWarning() << "Render backend is missing required symbols" << backend_;
library_.unload();
return false;
@@ -121,7 +121,7 @@ bool DynamicRenderer::Load()
qWarning() << "Render backend is not available" << backend_
<< library_.fileName();
if (backend_ == QStringLiteral("vulkan")) {
return FallbackToOpenGL();
return fallback_to_open_gl();
}
destroy_(handle_);
handle_ = nullptr;
@@ -133,9 +133,9 @@ bool DynamicRenderer::Load()
// Resolves the mandatory C ABI entry points from the loaded shared library.
// Optional information probes are resolved after the required render interface.
bool DynamicRenderer::ResolveFunctions()
bool DynamicRenderer::resolve_functions()
{
ResetFunctions();
reset_functions();
#define RESOLVE(member, type, symbol) \
member = reinterpret_cast<type>(library_.resolve(symbol)); \
if (!member) \
@@ -185,7 +185,7 @@ bool DynamicRenderer::ResolveFunctions()
// Discards a partially-created backend and restarts loading with the OpenGL
// backend. This keeps RenderManager's fallback path inside the adapter.
bool DynamicRenderer::FallbackToOpenGL()
bool DynamicRenderer::fallback_to_open_gl()
{
if (handle_ && destroy_) {
destroy_(handle_);
@@ -194,14 +194,14 @@ bool DynamicRenderer::FallbackToOpenGL()
if (library_.isLoaded()) {
library_.unload();
}
ResetFunctions();
reset_functions();
backend_ = QStringLiteral("opengl");
return Load();
return load();
}
// Clears all cached C function pointers so a failed backend cannot leave stale
// call targets behind for a later fallback load.
void DynamicRenderer::ResetFunctions()
void DynamicRenderer::reset_functions()
{
create_ = nullptr;
destroy_ = nullptr;
@@ -228,22 +228,22 @@ void DynamicRenderer::ResetFunctions()
}
// Returns backend metadata exposed by the dynamic library when available.
bool DynamicRenderer::GetBackendInfo(OakRenderBackendInfo *out_info) const
bool DynamicRenderer::get_backend_info(OakRenderBackendInfo *out_info) const
{
return handle_ && get_info_ && out_info && get_info_(handle_, out_info);
}
// Initializes the loaded backend using its own context/device creation path.
bool DynamicRenderer::Init()
bool DynamicRenderer::init()
{
return Load() && init_(handle_);
return load() && init_(handle_);
}
// Initializes an OpenGL backend against an existing widget context; non-OpenGL
// backends may ignore the context on the library side.
bool DynamicRenderer::InitWithOpenGLContext(QOpenGLContext *context)
bool DynamicRenderer::init_with_open_gl_context(QOpenGLContext *context)
{
if (!Load()) {
if (!load()) {
return false;
}
init_with_context_(handle_, context);
@@ -252,7 +252,7 @@ bool DynamicRenderer::InitWithOpenGLContext(QOpenGLContext *context)
// Forwards post-destroy cleanup to the backend while the library is still
// loaded and its symbols are still valid.
void DynamicRenderer::PostDestroy()
void DynamicRenderer::post_destroy()
{
if (handle_ && post_destroy_) {
post_destroy_(handle_);
@@ -261,7 +261,7 @@ void DynamicRenderer::PostDestroy()
// Runs backend post-initialization after Init/InitWithOpenGLContext has
// established the device or GL context.
void DynamicRenderer::PostInit()
void DynamicRenderer::post_init()
{
if (handle_) {
post_init_(handle_);
@@ -269,7 +269,7 @@ void DynamicRenderer::PostInit()
}
// Forwards render target clearing through the C ABI.
void DynamicRenderer::ClearDestination(Texture *texture, double r, double g,
void DynamicRenderer::clear_destination(Texture *texture, double r, double g,
double b, double a)
{
clear_destination_(handle_, texture, r, g, b, a);
@@ -277,7 +277,7 @@ void DynamicRenderer::ClearDestination(Texture *texture, double r, double g,
// Creates a backend-native shader and receives the result as an opaque QVariant
// because this first-generation ABI still shares C++/Qt types between modules.
QVariant DynamicRenderer::CreateNativeShader(ShaderCode code)
QVariant DynamicRenderer::create_native_shader(ShaderCode code)
{
QVariant out;
create_native_shader_(handle_, &code, &out);
@@ -285,13 +285,13 @@ QVariant DynamicRenderer::CreateNativeShader(ShaderCode code)
}
// Releases a backend-native shader handle.
void DynamicRenderer::DestroyNativeShader(QVariant shader)
void DynamicRenderer::destroy_native_shader(QVariant shader)
{
destroy_native_shader_(handle_, &shader);
}
// Uploads CPU pixel data into a backend texture through the dynamic ABI.
void DynamicRenderer::UploadToTexture(const QVariant &handle,
void DynamicRenderer::upload_to_texture(const QVariant &handle,
const VideoParams &params,
const void *data, int linesize)
{
@@ -299,7 +299,7 @@ void DynamicRenderer::UploadToTexture(const QVariant &handle,
}
// Downloads backend texture data into a caller-provided CPU buffer.
void DynamicRenderer::DownloadFromTexture(const QVariant &handle,
void DynamicRenderer::download_from_texture(const QVariant &handle,
const VideoParams &params, void *data,
int linesize)
{
@@ -307,13 +307,13 @@ void DynamicRenderer::DownloadFromTexture(const QVariant &handle,
}
// Waits for backend work to become visible to subsequent CPU or GPU consumers.
void DynamicRenderer::Flush()
void DynamicRenderer::flush()
{
flush_(handle_);
}
// Reads a single pixel through the backend-provided readback hook.
Color DynamicRenderer::GetPixelFromTexture(Texture *texture, const QPointF &pt)
Color DynamicRenderer::get_pixel_from_texture(Texture *texture, const QPointF &pt)
{
Color out;
get_pixel_from_texture_(handle_, texture, &pt, &out);
@@ -322,7 +322,7 @@ Color DynamicRenderer::GetPixelFromTexture(Texture *texture, const QPointF &pt)
// Exposes the wrapped OpenGL context when the backend is OpenGL; Vulkan returns
// null so callers can avoid GL-only paths.
QOpenGLContext *DynamicRenderer::OpenGLContext() const
QOpenGLContext *DynamicRenderer::open_gl_context() const
{
return opengl_context_ && handle_ ?
static_cast<QOpenGLContext *>(opengl_context_(handle_)) :
@@ -330,18 +330,18 @@ QOpenGLContext *DynamicRenderer::OpenGLContext() const
}
// Reports the effective backend after any load-time fallback has completed.
bool DynamicRenderer::IsOpenGL() const
bool DynamicRenderer::is_open_gl() const
{
return backend_ == QStringLiteral("opengl");
}
bool DynamicRenderer::IsVulkan() const
bool DynamicRenderer::is_vulkan() const
{
return backend_ == QStringLiteral("vulkan");
}
// Dispatches a shader blit to the loaded backend.
void DynamicRenderer::Blit(QVariant shader, AcceleratedJob &job,
void DynamicRenderer::blit(QVariant shader, AcceleratedJob &job,
Texture *destination, VideoParams destination_params,
bool clear_destination)
{
@@ -350,7 +350,7 @@ void DynamicRenderer::Blit(QVariant shader, AcceleratedJob &job,
}
// Allocates a backend-native texture and wraps its opaque handle in QVariant.
QVariant DynamicRenderer::CreateNativeTexture(int width, int height, int depth,
QVariant DynamicRenderer::create_native_texture(int width, int height, int depth,
PixelFormat format,
int channel_count,
const void *data, int linesize)
@@ -362,14 +362,14 @@ QVariant DynamicRenderer::CreateNativeTexture(int width, int height, int depth,
}
// Releases a backend-native texture handle.
void DynamicRenderer::DestroyNativeTexture(QVariant texture)
void DynamicRenderer::destroy_native_texture(QVariant texture)
{
destroy_native_texture_(handle_, &texture);
}
// Releases renderer-owned backend resources before the backend object itself is
// destroyed.
void DynamicRenderer::DestroyInternal()
void DynamicRenderer::destroy_internal()
{
if (handle_) {
destroy_internal_(handle_);
@@ -377,7 +377,7 @@ void DynamicRenderer::DestroyInternal()
}
// Exposes OFX OpenGL output binding through the dynamic backend when supported.
void DynamicRenderer::AttachOutputTexture(Texture *texture)
void DynamicRenderer::attach_output_texture(Texture *texture)
{
if (attach_output_texture_ && texture) {
QVariant id = texture->id();
@@ -386,7 +386,7 @@ void DynamicRenderer::AttachOutputTexture(Texture *texture)
}
// Clears any OFX output texture binding owned by the backend.
void DynamicRenderer::DetachOutputTexture()
void DynamicRenderer::detach_output_texture()
{
if (detach_output_texture_) {
detach_output_texture_(handle_);
+30 -30
View File
@@ -1,5 +1,5 @@
#ifndef DYNAMICRENDERER_H
#define DYNAMICRENDERER_H
#ifndef OAK_DYNAMICRENDERER_H
#define OAK_DYNAMICRENDERER_H
#include <QLibrary>
#include <QString>
@@ -21,14 +21,14 @@ public:
// Destroys backend resources and unloads the dynamic library.
virtual ~DynamicRenderer() override;
using Renderer::Blit;
using Renderer::blit;
// Loads the backend library, resolves C ABI symbols, and creates the handle.
bool Load();
bool load();
// Initializes an OpenGL backend with a caller-owned viewer context.
bool InitWithOpenGLContext(QOpenGLContext *context);
bool init_with_open_gl_context(QOpenGLContext *context);
// Retrieves backend metadata through the optional info entry point.
bool GetBackendInfo(OakRenderBackendInfo *out_info) const;
bool get_backend_info(OakRenderBackendInfo *out_info) const;
// Returns the effective backend after any load-time fallback.
QString backend_name() const
{
@@ -36,70 +36,70 @@ public:
}
// Initializes the backend using its default device/context path.
virtual bool Init() override;
virtual bool init() override;
// Runs backend post-destroy cleanup.
virtual void PostDestroy() override;
virtual void post_destroy() override;
// Runs backend post-init setup.
virtual void PostInit() override;
virtual void post_init() override;
// Clears either a native texture destination or the backend output target.
virtual void ClearDestination(Texture *texture = nullptr, double r = 0.0,
virtual void clear_destination(Texture *texture = nullptr, double r = 0.0,
double g = 0.0, double b = 0.0,
double a = 0.0) override;
// Creates a native shader through the dynamic backend.
virtual QVariant CreateNativeShader(ShaderCode code) override;
virtual QVariant create_native_shader(ShaderCode code) override;
// Destroys a native shader through the dynamic backend.
virtual void DestroyNativeShader(QVariant shader) override;
virtual void destroy_native_shader(QVariant shader) override;
// Uploads CPU pixels to a backend texture.
virtual void UploadToTexture(const QVariant &handle,
virtual void upload_to_texture(const QVariant &handle,
const VideoParams &params, const void *data,
int linesize) override;
// Downloads backend texture pixels to CPU memory.
virtual void DownloadFromTexture(const QVariant &handle,
virtual void download_from_texture(const QVariant &handle,
const VideoParams &params, void *data,
int linesize) override;
// Waits for backend work to complete.
virtual void Flush() override;
virtual void flush() override;
// Reads one pixel from a backend texture.
virtual Color GetPixelFromTexture(Texture *texture,
virtual Color get_pixel_from_texture(Texture *texture,
const QPointF &pt) override;
// Returns the wrapped OpenGL context for OpenGL backends.
virtual QOpenGLContext *OpenGLContext() const override;
virtual QOpenGLContext *open_gl_context() const override;
// Reports whether the effective backend is OpenGL.
virtual bool IsOpenGL() const override;
virtual bool is_open_gl() const override;
// Reports whether the effective backend is Vulkan.
virtual bool IsVulkan() const override;
virtual bool is_vulkan() const override;
// Attaches a texture for OFX OpenGL output when supported.
virtual void AttachOutputTexture(Texture *texture) override;
virtual void attach_output_texture(Texture *texture) override;
// Detaches any OFX output texture binding when supported.
virtual void DetachOutputTexture() override;
virtual void detach_output_texture() override;
protected:
// Dispatches a shader blit through the dynamic backend.
virtual void Blit(QVariant shader, AcceleratedJob &job,
virtual void blit(QVariant shader, AcceleratedJob &job,
Texture *destination, VideoParams destination_params,
bool clear_destination) override;
// Allocates a native texture through the dynamic backend.
virtual QVariant CreateNativeTexture(int width, int height, int depth,
virtual QVariant create_native_texture(int width, int height, int depth,
PixelFormat format, int channel_count,
const void *data = nullptr,
int linesize = 0) override;
// Releases a native texture through the dynamic backend.
virtual void DestroyNativeTexture(QVariant texture) override;
virtual void destroy_native_texture(QVariant texture) override;
// Releases backend-owned renderer resources.
virtual void DestroyInternal() override;
virtual void destroy_internal() override;
private:
// Resolves required backend C ABI symbols.
bool ResolveFunctions();
bool resolve_functions();
// Replaces a failed Vulkan backend with OpenGL.
bool FallbackToOpenGL();
bool fallback_to_open_gl();
// Clears all cached function pointers.
void ResetFunctions();
void reset_functions();
// Resolves the private backend library path.
QString LibraryFilename() const;
QString library_filename() const;
QString backend_;
QLibrary library_;
@@ -131,4 +131,4 @@ private:
}
#endif // DYNAMICRENDERER_H
#endif // OAK_DYNAMICRENDERER_H
+13 -13
View File
@@ -1,5 +1,5 @@
#ifndef RENDERBACKEND_C_H
#define RENDERBACKEND_C_H
#ifndef OAK_RENDERBACKEND_C_H
#define OAK_RENDERBACKEND_C_H
#include <stdbool.h>
#include <stdint.h>
@@ -20,20 +20,20 @@ typedef void *OakRenderBackendHandle;
/* Identifies the concrete backend behind a dynamically loaded library. */
enum OakRenderBackendKind {
OAK_RENDER_BACKEND_UNKNOWN = 0,
OAK_RENDER_BACKEND_OPENGL = 1,
OAK_RENDER_BACKEND_VULKAN = 2
oak_render_backend_unknown = 0,
oak_render_backend_opengl = 1,
oak_render_backend_vulkan = 2
};
/* Capability bits advertised by a backend through oak_renderer_get_info(). */
enum OakRenderBackendCapability {
OAK_RENDER_BACKEND_CAP_TEXTURES = 1ULL << 0,
OAK_RENDER_BACKEND_CAP_SHADERS = 1ULL << 1,
OAK_RENDER_BACKEND_CAP_BLIT = 1ULL << 2,
OAK_RENDER_BACKEND_CAP_READBACK = 1ULL << 3,
OAK_RENDER_BACKEND_CAP_VIEWER_CONTEXT = 1ULL << 4,
OAK_RENDER_BACKEND_CAP_INSTANCE = 1ULL << 5,
OAK_RENDER_BACKEND_CAP_DEVICE = 1ULL << 6
oak_render_backend_cap_textures = 1ULL << 0,
oak_render_backend_cap_shaders = 1ULL << 1,
oak_render_backend_cap_blit = 1ULL << 2,
oak_render_backend_cap_readback = 1ULL << 3,
oak_render_backend_cap_viewer_context = 1ULL << 4,
oak_render_backend_cap_instance = 1ULL << 5,
oak_render_backend_cap_device = 1ULL << 6
};
/* Static and runtime metadata returned by the backend. */
@@ -118,4 +118,4 @@ typedef void *(*OakBackendOpenGLContextFn)(OakRenderBackendHandle handle);
}
#endif
#endif // RENDERBACKEND_C_H
#endif // OAK_RENDERBACKEND_C_H
+6 -6
View File
@@ -16,8 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CANCELATOM_H
#define CANCELATOM_H
#ifndef OAK_CANCELATOM_H
#define OAK_CANCELATOM_H
#include <QMutex>
@@ -32,7 +32,7 @@ public:
{
}
bool IsCancelled()
bool is_cancelled()
{
QMutexLocker locker(&mutex_);
if (cancelled_) {
@@ -41,13 +41,13 @@ public:
return cancelled_;
}
void Cancel()
void cancel()
{
QMutexLocker locker(&mutex_);
cancelled_ = true;
}
bool HeardCancel()
bool heard_cancel()
{
QMutexLocker locker(&mutex_);
return heard_;
@@ -63,4 +63,4 @@ private:
}
#endif // CANCELATOM_H
#endif // OAK_CANCELATOM_H
+60 -60
View File
@@ -30,7 +30,7 @@
namespace olive
{
bool Renderer::GetColorContext(const ColorTransformJob &color_job,
bool Renderer::get_color_context(const ColorTransformJob &color_job,
Renderer::ColorContext *ctx)
{
QMutexLocker locker(&color_cache_mutex_);
@@ -47,37 +47,37 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job,
// Create shader description
QString ocio_func_name;
if (color_job.GetFunctionName().isEmpty()) {
if (color_job.get_function_name().isEmpty()) {
ocio_func_name = "OCIODisplay";
} else {
ocio_func_name = color_job.GetFunctionName();
ocio_func_name = color_job.get_function_name();
}
auto shader_desc = OCIO::GpuShaderDesc::CreateShaderDesc();
shader_desc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_ES_3_0);
auto shader_desc = ocio::GpuShaderDesc::CreateShaderDesc();
shader_desc->setLanguage(ocio::GPU_LANGUAGE_GLSL_ES_3_0);
shader_desc->setFunctionName(ocio_func_name.toUtf8());
shader_desc->setResourcePrefix("ocio_");
// Generate shader
color_job.GetColorProcessor()
->GetProcessor()
color_job.get_color_processor()
->get_processor()
->getDefaultGPUProcessor()
->extractGpuShaderInfo(shader_desc);
ShaderCode code;
if (const Node *shader_src = color_job.CustomShaderSource()) {
if (const Node *shader_src = color_job.custom_shader_source()) {
// Use shader code from associated node
code = shader_src->GetShaderCode(
{ color_job.CustomShaderID(), shader_desc->getShaderText() });
code = shader_src->get_shader_code(
{ color_job.custom_shader_id(), shader_desc->getShaderText() });
} else {
// Generate shader code using OCIO stub and our auto-generated name
code = FileFunctions::ReadFileAsString(
code = FileFunctions::read_file_as_string(
QStringLiteral(":/shaders/colormanage.frag"));
code.set_frag_code(
code.frag_code().arg(shader_desc->getShaderText()));
}
// Try to compile shader
color_ctx.compiled_shader = CreateNativeShader(code);
color_ctx.compiled_shader = create_native_shader(code);
if (color_ctx.compiled_shader.isNull()) {
return false;
@@ -88,7 +88,7 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job,
const char *tex_name = nullptr;
const char *sampler_name = nullptr;
unsigned int edge_len = 0;
OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR;
ocio::Interpolation interpolation = ocio::INTERP_LINEAR;
shader_desc->get3DTexture(i, tex_name, sampler_name, edge_len,
interpolation);
@@ -107,14 +107,14 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job,
}
// Allocate 3D LUT
color_ctx.lut3d_textures[i].texture = CreateTexture(
VideoParams(edge_len, edge_len, edge_len, PixelFormat::F32,
VideoParams::kRGBChannelCount),
color_ctx.lut3d_textures[i].texture = create_texture(
VideoParams(edge_len, edge_len, edge_len, PixelFormat::f32,
VideoParams::k_rgb_channel_count),
values);
color_ctx.lut3d_textures[i].name = sampler_name;
color_ctx.lut3d_textures[i].interpolation =
(interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest :
Texture::kLinear;
(interpolation == ocio::INTERP_NEAREST) ? Texture::k_nearest :
Texture::k_linear;
}
color_ctx.lut1d_textures.resize(shader_desc->getNumTextures());
@@ -122,13 +122,13 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job,
const char *tex_name = nullptr;
const char *sampler_name = nullptr;
unsigned int width = 0, height = 0;
OCIO::GpuShaderDesc::TextureType channel =
OCIO::GpuShaderDesc::TEXTURE_RGB_CHANNEL;
OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR;
ocio::GpuShaderDesc::TextureType channel =
ocio::GpuShaderDesc::TEXTURE_RGB_CHANNEL;
ocio::Interpolation interpolation = ocio::INTERP_LINEAR;
#if OCIO_VERSION_MAJOR > 2 || \
(OCIO_VERSION_MAJOR == 2 && OCIO_VERSION_MINOR >= 3)
OCIO::GpuShaderDesc::TextureDimensions dimensions =
OCIO::GpuShaderDesc::TEXTURE_2D;
ocio::GpuShaderDesc::TextureDimensions dimensions =
ocio::GpuShaderDesc::TEXTURE_2D;
shader_desc->getTexture(i, tex_name, sampler_name, width, height,
channel, dimensions, interpolation);
#else
@@ -151,17 +151,17 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job,
// Allocate 1D LUT
int lut_channels =
(channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ?
(channel == ocio::GpuShaderDesc::TEXTURE_RED_CHANNEL) ?
1 :
VideoParams::kRGBChannelCount;
VideoParams lut_params(width, height, PixelFormat::F32,
VideoParams::k_rgb_channel_count;
VideoParams lut_params(width, height, PixelFormat::f32,
lut_channels);
color_ctx.lut1d_textures[i].texture =
CreateTexture(lut_params, values);
create_texture(lut_params, values);
color_ctx.lut1d_textures[i].name = sampler_name;
color_ctx.lut1d_textures[i].interpolation =
(interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest :
Texture::kLinear;
(interpolation == ocio::INTERP_NEAREST) ? Texture::k_nearest :
Texture::k_linear;
}
locker.relock();
@@ -171,59 +171,59 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job,
}
}
void Renderer::BlitColorManaged(const ColorTransformJob &color_job,
void Renderer::blit_color_managed(const ColorTransformJob &color_job,
Texture *destination, const VideoParams &params)
{
ColorContext color_ctx;
if (!GetColorContext(color_job, &color_ctx)) {
if (!get_color_context(color_job, &color_ctx)) {
ShaderJob fallback_job;
fallback_job.Insert(QStringLiteral("ove_maintex"),
color_job.GetInputTexture());
fallback_job.Insert(QStringLiteral("ove_mvpmat"),
NodeValue(NodeValue::kMatrix,
color_job.GetTransformMatrix()));
fallback_job.insert(QStringLiteral("ove_maintex"),
color_job.get_input_texture());
fallback_job.insert(QStringLiteral("ove_mvpmat"),
NodeValue(NodeValue::k_matrix,
color_job.get_transform_matrix()));
if (destination) {
BlitToTexture(GetDefaultShader(), fallback_job, destination,
color_job.IsClearDestinationEnabled());
blit_to_texture(get_default_shader(), fallback_job, destination,
color_job.is_clear_destination_enabled());
} else {
Blit(GetDefaultShader(), fallback_job, params,
color_job.IsClearDestinationEnabled());
blit(get_default_shader(), fallback_job, params,
color_job.is_clear_destination_enabled());
}
return;
}
ShaderJob job;
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())));
job.Insert(QStringLiteral("ove_force_opaque"),
NodeValue(NodeValue::kBoolean, color_job.GetForceOpaque()));
job.Insert(color_job.GetValues());
job.insert(QStringLiteral("ove_maintex"), color_job.get_input_texture());
job.insert(QStringLiteral("ove_mvpmat"),
NodeValue(NodeValue::k_matrix, color_job.get_transform_matrix()));
job.insert(QStringLiteral("ove_cropmatrix"),
NodeValue(NodeValue::k_matrix,
color_job.get_crop_matrix().inverted()));
job.insert(QStringLiteral("ove_maintex_alpha"),
NodeValue(NodeValue::k_int,
int(color_job.get_input_alpha_association())));
job.insert(QStringLiteral("ove_force_opaque"),
NodeValue(NodeValue::k_boolean, color_job.get_force_opaque()));
job.insert(color_job.get_values());
foreach (const ColorContext::LUT &l, color_ctx.lut3d_textures) {
job.Insert(l.name, NodeValue(NodeValue::kTexture,
job.insert(l.name, NodeValue(NodeValue::k_texture,
QVariant::fromValue(l.texture)));
job.SetInterpolation(l.name, l.interpolation);
job.set_interpolation(l.name, l.interpolation);
}
foreach (const ColorContext::LUT &l, color_ctx.lut1d_textures) {
job.Insert(l.name, NodeValue(NodeValue::kTexture,
job.insert(l.name, NodeValue(NodeValue::k_texture,
QVariant::fromValue(l.texture)));
job.SetInterpolation(l.name, l.interpolation);
job.set_interpolation(l.name, l.interpolation);
}
if (destination) {
BlitToTexture(color_ctx.compiled_shader, job, destination,
color_job.IsClearDestinationEnabled());
blit_to_texture(color_ctx.compiled_shader, job, destination,
color_job.is_clear_destination_enabled());
} else {
Blit(color_ctx.compiled_shader, job, params,
color_job.IsClearDestinationEnabled());
blit(color_ctx.compiled_shader, job, params,
color_job.is_clear_destination_enabled());
}
}
+25 -25
View File
@@ -39,40 +39,40 @@ ColorProcessor::ColorProcessor(ColorManager *config, const QString &input,
// Resolve role names (e.g. "scene_linear") to canonical colorspace names
// so they can be passed to getProcessor()/DisplayViewTransform.
QString resolved_input = input;
OCIO::ConstConfigRcPtr ocio_config = config->GetConfig();
ocio::ConstConfigRcPtr ocio_config = config->get_config();
if (ocio_config && ocio_config->hasRole(input.toUtf8())) {
resolved_input = ocio_config->getCanonicalName(input.toUtf8());
}
const QString &output = (transform.output().isEmpty()) ?
config->GetDefaultDisplay() :
config->get_default_display() :
transform.output();
if (transform.is_display()) {
const QString &view = (transform.view().isEmpty()) ?
config->GetDefaultView(output) :
config->get_default_view(output) :
transform.view();
auto display_transform = OCIO::DisplayViewTransform::Create();
auto display_transform = ocio::DisplayViewTransform::Create();
display_transform->setSrc(resolved_input.toUtf8());
display_transform->setDisplay(output.toUtf8());
display_transform->setView(view.toUtf8());
display_transform->setDirection(direction == kNormal ?
OCIO::TRANSFORM_DIR_FORWARD :
OCIO::TRANSFORM_DIR_INVERSE);
display_transform->setDirection(direction == k_normal ?
ocio::TRANSFORM_DIR_FORWARD :
ocio::TRANSFORM_DIR_INVERSE);
if (transform.look().isEmpty()) {
processor_ = ocio_config->getProcessor(display_transform);
} else {
auto group = OCIO::GroupTransform::Create();
auto group = ocio::GroupTransform::Create();
const char *out_cs =
OCIO::LookTransform::GetLooksResultColorSpace(
ocio::LookTransform::GetLooksResultColorSpace(
ocio_config, ocio_config->getCurrentContext(),
transform.look().toUtf8());
auto lt = OCIO::LookTransform::Create();
auto lt = ocio::LookTransform::Create();
lt->setSrc(resolved_input.toUtf8());
lt->setDst(out_cs);
lt->setLooks(transform.look().toUtf8());
@@ -86,7 +86,7 @@ ColorProcessor::ColorProcessor(ColorManager *config, const QString &input,
}
} else {
if (direction == kNormal) {
if (direction == k_normal) {
processor_ = ocio_config->getProcessor(resolved_input.toUtf8(),
output.toUtf8());
} else {
@@ -98,41 +98,41 @@ ColorProcessor::ColorProcessor(ColorManager *config, const QString &input,
if (processor_) {
cpu_processor_ = processor_->getDefaultCPUProcessor();
}
} catch (OCIO::Exception &e) {
} catch (ocio::Exception &e) {
qWarning() << "ColorProcessor exception:" << e.what();
}
}
ColorProcessor::ColorProcessor(OCIO::ConstProcessorRcPtr processor)
ColorProcessor::ColorProcessor(ocio::ConstProcessorRcPtr processor)
{
processor_ = processor;
cpu_processor_ = processor_ ? processor_->getDefaultCPUProcessor() :
nullptr;
}
void ColorProcessor::ConvertFrame(Frame *f)
void ColorProcessor::convert_frame(Frame *f)
{
if (!cpu_processor_) {
return;
}
OCIO::BitDepth ocio_bit_depth =
OCIOUtils::GetOCIOBitDepthFromPixelFormat(f->format());
ocio::BitDepth ocio_bit_depth =
OCIOUtils::get_ocio_bit_depth_from_pixel_format(f->format());
if (ocio_bit_depth == OCIO::BIT_DEPTH_UNKNOWN) {
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(),
ocio::PackedImageDesc img(f->data(), f->width(), f->height(),
f->channel_count(), ocio_bit_depth,
OCIO::AutoStride, OCIO::AutoStride,
ocio::AutoStride, ocio::AutoStride,
f->linesize_bytes());
cpu_processor_->apply(img);
}
Color ColorProcessor::ConvertColor(const Color &in)
Color ColorProcessor::convert_color(const Color &in)
{
if (!cpu_processor_) {
return in;
@@ -147,7 +147,7 @@ Color ColorProcessor::ConvertColor(const Color &in)
return Color(c[0], c[1], c[2], c[3]);
}
ColorProcessorPtr ColorProcessor::Create(ColorManager *config,
ColorProcessorPtr ColorProcessor::create(ColorManager *config,
const QString &input,
const ColorTransform &transform,
Direction direction)
@@ -156,19 +156,19 @@ ColorProcessorPtr ColorProcessor::Create(ColorManager *config,
direction);
}
ColorProcessorPtr ColorProcessor::Create(OCIO::ConstProcessorRcPtr processor)
ColorProcessorPtr ColorProcessor::create(ocio::ConstProcessorRcPtr processor)
{
return std::make_shared<ColorProcessor>(processor);
}
OCIO::ConstProcessorRcPtr ColorProcessor::GetProcessor()
ocio::ConstProcessorRcPtr ColorProcessor::get_processor()
{
return processor_;
}
void ColorProcessor::ConvertFrame(FramePtr f)
void ColorProcessor::convert_frame(FramePtr f)
{
ConvertFrame(f.get());
convert_frame(f.get());
}
}
+15 -15
View File
@@ -19,8 +19,8 @@
***/
#ifndef COLORPROCESSOR_H
#define COLORPROCESSOR_H
#ifndef OAK_COLORPROCESSOR_H
#define OAK_COLORPROCESSOR_H
#include "codec/frame.h"
#include "common/ocioutils.h"
@@ -36,26 +36,26 @@ using ColorProcessorPtr = std::shared_ptr<ColorProcessor>;
class ColorProcessor {
public:
enum Direction { kNormal, kInverse };
enum Direction { k_normal, k_inverse };
ColorProcessor(ColorManager *config, const QString &input,
const ColorTransform &dest_space,
Direction direction = kNormal);
ColorProcessor(OCIO::ConstProcessorRcPtr processor);
Direction direction = k_normal);
ColorProcessor(ocio::ConstProcessorRcPtr processor);
DISABLE_COPY_MOVE(ColorProcessor)
static ColorProcessorPtr Create(ColorManager *config, const QString &input,
static ColorProcessorPtr create(ColorManager *config, const QString &input,
const ColorTransform &dest_space,
Direction direction = kNormal);
static ColorProcessorPtr Create(OCIO::ConstProcessorRcPtr processor);
Direction direction = k_normal);
static ColorProcessorPtr create(ocio::ConstProcessorRcPtr processor);
OCIO::ConstProcessorRcPtr GetProcessor();
ocio::ConstProcessorRcPtr get_processor();
void ConvertFrame(FramePtr f);
void ConvertFrame(Frame *f);
void convert_frame(FramePtr f);
void convert_frame(Frame *f);
Color ConvertColor(const Color &in);
Color convert_color(const Color &in);
const char *id() const
{
@@ -63,9 +63,9 @@ public:
}
private:
OCIO::ConstProcessorRcPtr processor_;
ocio::ConstProcessorRcPtr processor_;
OCIO::ConstCPUProcessorRcPtr cpu_processor_;
ocio::ConstCPUProcessorRcPtr cpu_processor_;
};
using ColorProcessorChain = QVector<ColorProcessorPtr>;
@@ -74,4 +74,4 @@ using ColorProcessorChain = QVector<ColorProcessorPtr>;
Q_DECLARE_METATYPE(olive::ColorProcessorPtr)
#endif // COLORPROCESSOR_H
#endif // OAK_COLORPROCESSOR_H
+3 -3
View File
@@ -19,8 +19,8 @@
***/
#ifndef COLORPROCESSORCACHE_H
#define COLORPROCESSORCACHE_H
#ifndef OAK_COLORPROCESSORCACHE_H
#define OAK_COLORPROCESSORCACHE_H
#include "render/colorprocessor.h"
@@ -31,4 +31,4 @@ using ColorProcessorCache = QHash<QString, ColorProcessorPtr>;
}
#endif // COLORPROCESSORCACHE_H
#endif // OAK_COLORPROCESSORCACHE_H
+3 -3
View File
@@ -19,8 +19,8 @@
***/
#ifndef COLORTRANSFORM_H
#define COLORTRANSFORM_H
#ifndef OAK_COLORTRANSFORM_H
#define OAK_COLORTRANSFORM_H
#include <QString>
@@ -89,4 +89,4 @@ private:
Q_DECLARE_METATYPE(olive::ColorTransform)
#endif // COLORTRANSFORM_H
#endif // OAK_COLORTRANSFORM_H
+61 -61
View File
@@ -41,13 +41,13 @@ DiskManager *DiskManager::instance_ = nullptr;
DiskManager::DiskManager()
{
// Add default cache location
QFile default_disk_cache_file(GetDefaultDiskCacheConfigFile());
QFile default_disk_cache_file(get_default_disk_cache_config_file());
if (default_disk_cache_file.open(QFile::ReadOnly)) {
QString default_dir = default_disk_cache_file.readAll();
if (!default_dir.isEmpty()) {
if (FileFunctions::DirectoryIsValid(default_dir)) {
GetOpenFolder(default_dir);
if (FileFunctions::directory_is_valid(default_dir)) {
get_open_folder(default_dir);
} else {
QMessageBox::warning(
nullptr, tr("Disk Cache Error"),
@@ -60,10 +60,10 @@ DiskManager::DiskManager()
// If no custom default was loaded, load default
if (open_folders_.isEmpty()) {
GetOpenFolder(GetDefaultDiskCachePath());
get_open_folder(get_default_disk_cache_path());
}
QFile disk_cache_index(QDir(FileFunctions::GetConfigurationLocation())
QFile disk_cache_index(QDir(FileFunctions::get_configuration_location())
.filePath(QStringLiteral("diskcache2")));
if (disk_cache_index.open(QFile::ReadOnly)) {
@@ -71,7 +71,7 @@ DiskManager::DiskManager()
QString line;
while (stream.readLineInto(&line)) {
GetOpenFolder(line);
get_open_folder(line);
}
disk_cache_index.close();
@@ -80,22 +80,22 @@ DiskManager::DiskManager()
DiskManager::~DiskManager()
{
QFile default_disk_cache_file(GetDefaultDiskCacheConfigFile());
QFile default_disk_cache_file(get_default_disk_cache_config_file());
if (default_disk_cache_file.open(QFile::WriteOnly)) {
if (GetDefaultDiskCachePath() != GetDefaultCachePath()) {
default_disk_cache_file.write(GetDefaultCachePath().toUtf8());
if (get_default_disk_cache_path() != get_default_cache_path()) {
default_disk_cache_file.write(get_default_cache_path().toUtf8());
}
default_disk_cache_file.close();
}
}
void DiskManager::CreateInstance()
void DiskManager::create_instance()
{
instance_ = new DiskManager();
}
void DiskManager::DestroyInstance()
void DiskManager::destroy_instance()
{
delete instance_;
instance_ = nullptr;
@@ -106,59 +106,59 @@ DiskManager *DiskManager::instance()
return instance_;
}
void DiskManager::Accessed(const QString &cache_folder, const QString &filename)
void DiskManager::accessed(const QString &cache_folder, const QString &filename)
{
DiskCacheFolder *f = GetOpenFolder(cache_folder);
DiskCacheFolder *f = get_open_folder(cache_folder);
f->Accessed(filename);
f->accessed(filename);
}
void DiskManager::CreatedFile(const QString &cache_folder,
void DiskManager::created_file(const QString &cache_folder,
const QString &filename)
{
DiskCacheFolder *f = GetOpenFolder(cache_folder);
DiskCacheFolder *f = get_open_folder(cache_folder);
f->CreatedFile(filename);
f->created_file(filename);
}
void DiskManager::DeleteSpecificFile(const QString &filename)
void DiskManager::delete_specific_file(const QString &filename)
{
foreach (DiskCacheFolder *f, open_folders_) {
f->DeleteSpecificFile(filename);
f->delete_specific_file(filename);
}
}
bool DiskManager::ClearDiskCache(const QString &cache_folder)
bool DiskManager::clear_disk_cache(const QString &cache_folder)
{
DiskCacheFolder *f = GetOpenFolder(cache_folder);
DiskCacheFolder *f = get_open_folder(cache_folder);
return f->ClearCache();
return f->clear_cache();
}
DiskCacheFolder *DiskManager::GetOpenFolder(const QString &path)
DiskCacheFolder *DiskManager::get_open_folder(const QString &path)
{
// If path is empty, this must mean default
if (path.isEmpty()) {
return GetDefaultCacheFolder();
return get_default_cache_folder();
}
// See if we have an existing path with this name
foreach (DiskCacheFolder *f, open_folders_) {
if (f->GetPath() == path) {
if (f->get_path() == path) {
return f;
}
}
// We must have to open this folder
DiskCacheFolder *f = new DiskCacheFolder(path, this);
connect(f, &DiskCacheFolder::DeletedFrame, this,
&DiskManager::DeletedFrame);
connect(f, &DiskCacheFolder::deleted_frame, this,
&DiskManager::deleted_frame);
open_folders_.append(f);
return f;
}
bool DiskManager::ShowDiskCacheChangeConfirmationDialog(QWidget *parent)
bool DiskManager::show_disk_cache_change_confirmation_dialog(QWidget *parent)
{
return (
QMessageBox::question(
@@ -168,30 +168,30 @@ bool DiskManager::ShowDiskCacheChangeConfirmationDialog(QWidget *parent)
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok);
}
QString DiskManager::GetDefaultDiskCacheConfigFile()
QString DiskManager::get_default_disk_cache_config_file()
{
return QDir(FileFunctions::GetConfigurationLocation())
return QDir(FileFunctions::get_configuration_location())
.filePath(QStringLiteral("defaultdiskcache"));
}
QString DiskManager::GetDefaultDiskCachePath()
QString DiskManager::get_default_disk_cache_path()
{
return QDir(QStandardPaths::writableLocation(
QStandardPaths::AppLocalDataLocation))
.filePath("mediacache");
}
void DiskManager::ShowDiskCacheSettingsDialog(DiskCacheFolder *folder,
void DiskManager::show_disk_cache_settings_dialog(DiskCacheFolder *folder,
QWidget *parent)
{
DiskCacheDialog d(folder, parent);
d.exec();
}
void DiskManager::ShowDiskCacheSettingsDialog(const QString &path,
void DiskManager::show_disk_cache_settings_dialog(const QString &path,
QWidget *parent)
{
if (!FileFunctions::DirectoryIsValid(path)) {
if (!FileFunctions::directory_is_valid(path)) {
QMessageBox::critical(
parent, tr("Disk Cache Error"),
tr("Failed to open disk cache at \"%1\". Try a different folder.")
@@ -199,28 +199,28 @@ void DiskManager::ShowDiskCacheSettingsDialog(const QString &path,
return;
}
DiskCacheFolder *folder = GetOpenFolder(path);
DiskCacheFolder *folder = get_open_folder(path);
ShowDiskCacheSettingsDialog(folder, parent);
show_disk_cache_settings_dialog(folder, parent);
}
DiskCacheFolder::DiskCacheFolder(const QString &path, QObject *parent)
: QObject(parent)
{
SetPath(path);
set_path(path);
save_timer_.setInterval(OLIVE_CONFIG("DiskCacheSaveInterval").toInt());
save_timer_.setInterval(OAK_CONFIG("DiskCacheSaveInterval").toInt());
connect(&save_timer_, &QTimer::timeout, this,
&DiskCacheFolder::SaveDiskCacheIndex);
&DiskCacheFolder::save_disk_cache_index);
save_timer_.start();
}
DiskCacheFolder::~DiskCacheFolder()
{
CloseCacheFolder();
close_cache_folder();
}
bool DiskCacheFolder::ClearCache()
bool DiskCacheFolder::clear_cache()
{
bool deleted_files = true;
@@ -231,7 +231,7 @@ bool DiskCacheFolder::ClearCache()
QString filename = i.key();
if (QFile::remove(filename) || !QFileInfo::exists(filename)) {
emit DeletedFrame(path_, filename);
emit deleted_frame(path_, filename);
i = disk_data_.erase(i);
} else {
qWarning() << "Failed to delete" << filename;
@@ -243,7 +243,7 @@ bool DiskCacheFolder::ClearCache()
return deleted_files;
}
void DiskCacheFolder::Accessed(const QString &filename)
void DiskCacheFolder::accessed(const QString &filename)
{
if (!disk_data_.contains(filename)) {
return;
@@ -252,7 +252,7 @@ void DiskCacheFolder::Accessed(const QString &filename)
disk_data_[filename].access_time = QDateTime::currentMSecsSinceEpoch();
}
void DiskCacheFolder::CreatedFile(const QString &filename)
void DiskCacheFolder::created_file(const QString &filename)
{
qint64 file_size = QFile(filename).size();
@@ -262,19 +262,19 @@ void DiskCacheFolder::CreatedFile(const QString &filename)
consumption_ += file_size;
while (consumption_ > limit_) {
DeleteLeastRecent();
delete_least_recent();
}
}
void DiskCacheFolder::SetPath(const QString &path)
void DiskCacheFolder::set_path(const QString &path)
{
// If this is currently set to a folder, close it out now
CloseCacheFolder();
close_cache_folder();
// Signal that disk cache is gone
if (!disk_data_.empty()) {
for (auto it = disk_data_.cbegin(); it != disk_data_.cend(); it++) {
emit DeletedFrame(path_, it.key());
emit deleted_frame(path_, it.key());
}
disk_data_.clear();
}
@@ -289,7 +289,7 @@ void DiskCacheFolder::SetPath(const QString &path)
// Attempt to load existing index file from path
QDir path_dir(path_);
FileFunctions::DirectoryIsValid(path_dir);
FileFunctions::directory_is_valid(path_dir);
index_path_ = path_dir.filePath(QStringLiteral("index"));
@@ -320,7 +320,7 @@ void DiskCacheFolder::SetPath(const QString &path)
}
}
bool DiskCacheFolder::DeleteFileInternal(
bool DiskCacheFolder::delete_file_internal(
QMap<QString, HashTime>::iterator hash_to_delete)
{
// Cache HashTime object
@@ -337,26 +337,26 @@ bool DiskCacheFolder::DeleteFileInternal(
// Reduce consumption
consumption_ -= ht.file_size;
emit DeletedFrame(path_, filename);
emit deleted_frame(path_, filename);
return true;
}
return false;
}
bool DiskCacheFolder::DeleteSpecificFile(const QString &f)
bool DiskCacheFolder::delete_specific_file(const QString &f)
{
for (auto it = disk_data_.begin(); it != disk_data_.end(); it++) {
if (it.key() == f) {
// Break out of this loop, assuming we'll only have one instance of each filename
return DeleteFileInternal(it);
// Break out of this loop, assuming we'll only have one instance_ of each filename
return delete_file_internal(it);
}
}
return false;
}
bool DiskCacheFolder::DeleteLeastRecent()
bool DiskCacheFolder::delete_least_recent()
{
auto hash_to_delete = disk_data_.begin();
@@ -367,10 +367,10 @@ bool DiskCacheFolder::DeleteLeastRecent()
}
}
bool e = DeleteFileInternal(hash_to_delete);
bool e = delete_file_internal(hash_to_delete);
if (e) {
Core::instance()->WarnCacheFull();
Core::instance()->warn_cache_full();
}
return e;
@@ -379,7 +379,7 @@ bool DiskCacheFolder::DeleteLeastRecent()
}
}
void DiskCacheFolder::CloseCacheFolder()
void DiskCacheFolder::close_cache_folder()
{
if (path_.isEmpty()) {
return;
@@ -388,14 +388,14 @@ void DiskCacheFolder::CloseCacheFolder()
if (clear_on_close_) {
// If we're not moving to new and we're set to clear on close, clear now or else it'll never
// get cleared later
ClearCache();
clear_cache();
}
// Save current cache index
SaveDiskCacheIndex();
save_disk_cache_index();
}
void DiskCacheFolder::SaveDiskCacheIndex()
void DiskCacheFolder::save_disk_cache_index()
{
QFile cache_index_file(index_path_);
+36 -36
View File
@@ -19,8 +19,8 @@
***/
#ifndef DISKMANAGER_H
#define DISKMANAGER_H
#ifndef OAK_DISKMANAGER_H
#define OAK_DISKMANAGER_H
#include <QMap>
#include <QMutex>
@@ -40,43 +40,43 @@ public:
virtual ~DiskCacheFolder() override;
bool ClearCache();
bool clear_cache();
void Accessed(const QString &filename);
void accessed(const QString &filename);
void CreatedFile(const QString &filename);
void created_file(const QString &filename);
const QString &GetPath() const
const QString &get_path() const
{
return path_;
}
void SetPath(const QString &path);
void set_path(const QString &path);
qint64 GetLimit() const
qint64 get_limit() const
{
return limit_;
}
bool GetClearOnClose() const
bool get_clear_on_close() const
{
return clear_on_close_;
}
void SetLimit(qint64 l)
void set_limit(qint64 l)
{
limit_ = l;
}
void SetClearOnClose(bool e)
void set_clear_on_close(bool e)
{
clear_on_close_ = e;
}
bool DeleteSpecificFile(const QString &f);
bool delete_specific_file(const QString &f);
signals:
void DeletedFrame(const QString &path, const QString &filename);
void deleted_frame(const QString &path, const QString &filename);
private:
struct HashTime {
@@ -84,11 +84,11 @@ private:
qint64 access_time;
};
bool DeleteFileInternal(QMap<QString, HashTime>::iterator hash_to_delete);
bool delete_file_internal(QMap<QString, HashTime>::iterator hash_to_delete);
bool DeleteLeastRecent();
bool delete_least_recent();
void CloseCacheFolder();
void close_cache_folder();
QString path_;
@@ -105,58 +105,58 @@ private:
QTimer save_timer_;
private slots:
void SaveDiskCacheIndex();
void save_disk_cache_index();
};
class DiskManager : public QObject {
Q_OBJECT
public:
static void CreateInstance();
static void create_instance();
static void DestroyInstance();
static void destroy_instance();
static DiskManager *instance();
bool ClearDiskCache(const QString &cache_folder);
bool clear_disk_cache(const QString &cache_folder);
DiskCacheFolder *GetDefaultCacheFolder() const
DiskCacheFolder *get_default_cache_folder() const
{
// The first folder will always be the default
return open_folders_.first();
}
const QString &GetDefaultCachePath() const
const QString &get_default_cache_path() const
{
return GetDefaultCacheFolder()->GetPath();
return get_default_cache_folder()->get_path();
}
DiskCacheFolder *GetOpenFolder(const QString &path);
DiskCacheFolder *get_open_folder(const QString &path);
const QVector<DiskCacheFolder *> &GetOpenFolders() const
const QVector<DiskCacheFolder *> &get_open_folders() const
{
return open_folders_;
}
static bool ShowDiskCacheChangeConfirmationDialog(QWidget *parent);
static bool show_disk_cache_change_confirmation_dialog(QWidget *parent);
static QString GetDefaultDiskCacheConfigFile();
static QString get_default_disk_cache_config_file();
static QString GetDefaultDiskCachePath();
static QString get_default_disk_cache_path();
void ShowDiskCacheSettingsDialog(DiskCacheFolder *folder, QWidget *parent);
void ShowDiskCacheSettingsDialog(const QString &path, QWidget *parent);
void show_disk_cache_settings_dialog(DiskCacheFolder *folder, QWidget *parent);
void show_disk_cache_settings_dialog(const QString &path, QWidget *parent);
public slots:
void Accessed(const QString &cache_folder, const QString &filename);
void accessed(const QString &cache_folder, const QString &filename);
void CreatedFile(const QString &cache_folder, const QString &filename);
void created_file(const QString &cache_folder, const QString &filename);
void DeleteSpecificFile(const QString &filename);
void delete_specific_file(const QString &filename);
signals:
void DeletedFrame(const QString &path, const QString &filename);
void deleted_frame(const QString &path, const QString &filename);
void InvalidateProject(Project *p);
void invalidate_project(Project *p);
private:
DiskManager();
@@ -170,4 +170,4 @@ private:
}
#endif // DISKMANAGER_H
#endif // OAK_DISKMANAGER_H
+91 -91
View File
@@ -42,37 +42,37 @@ FrameHashCache::FrameHashCache(QObject *parent)
: super(parent)
{
if (DiskManager::instance()) {
connect(DiskManager::instance(), &DiskManager::DeletedFrame, this,
&FrameHashCache::HashDeleted);
connect(DiskManager::instance(), &DiskManager::InvalidateProject, this,
&FrameHashCache::ProjectInvalidated);
connect(DiskManager::instance(), &DiskManager::deleted_frame, this,
&FrameHashCache::hash_deleted);
connect(DiskManager::instance(), &DiskManager::invalidate_project, this,
&FrameHashCache::project_invalidated);
}
}
void FrameHashCache::SetTimebase(const rational &tb)
void FrameHashCache::set_timebase(const Rational &tb)
{
timebase_ = tb;
}
void FrameHashCache::ValidateTimestamp(const int64_t &ts)
void FrameHashCache::validate_timestamp(const int64_t &ts)
{
TimeRange frame_range(ToTime(ts), ToTime(ts + 1));
Validate(frame_range);
TimeRange frame_range(to_time(ts), to_time(ts + 1));
validate(frame_range);
}
void FrameHashCache::ValidateTime(const rational &time)
void FrameHashCache::validate_time(const Rational &time)
{
Validate(TimeRange(time, time + timebase_));
validate(TimeRange(time, time + timebase_));
}
QString FrameHashCache::GetValidCacheFilename(const rational &time) const
QString FrameHashCache::get_valid_cache_filename(const Rational &time) const
{
if (IsFrameCached(time)) {
return CachePathName(time);
} else if (!GetPassthroughs().empty()) {
for (const Passthrough &p : GetPassthroughs()) {
if (p.Contains(time)) {
return CachePathName(GetCacheDirectory(), p.cache, time,
if (is_frame_cached(time)) {
return cache_path_name(time);
} else if (!get_passthroughs().empty()) {
for (const Passthrough &p : get_passthroughs()) {
if (p.contains(time)) {
return cache_path_name(get_cache_directory(), p.cache, time,
timebase_);
}
}
@@ -81,12 +81,12 @@ QString FrameHashCache::GetValidCacheFilename(const rational &time) const
return QString();
}
bool FrameHashCache::SaveCacheFrame(const int64_t &time, FramePtr frame) const
bool FrameHashCache::save_cache_frame(const int64_t &time, FramePtr frame) const
{
return SaveCacheFrame(GetCacheDirectory(), GetUuid(), time, frame);
return save_cache_frame(get_cache_directory(), get_uuid(), time, frame);
}
bool FrameHashCache::SaveCacheFrame(const QString &cache_path,
bool FrameHashCache::save_cache_frame(const QString &cache_path,
const QUuid &uuid, const int64_t &time,
FramePtr frame)
{
@@ -95,13 +95,13 @@ bool FrameHashCache::SaveCacheFrame(const QString &cache_path,
return false;
}
QString fn = CachePathName(cache_path, uuid, time);
QString fn = cache_path_name(cache_path, uuid, time);
bool ret = SaveCacheFrame(fn, frame);
bool ret = save_cache_frame(fn, frame);
// Register frame with the disk manager
if (ret) {
QMetaObject::invokeMethod(DiskManager::instance(), "CreatedFile",
QMetaObject::invokeMethod(DiskManager::instance(), "created_file",
Q_ARG(QString, cache_path),
Q_ARG(QString, fn));
}
@@ -109,22 +109,22 @@ bool FrameHashCache::SaveCacheFrame(const QString &cache_path,
return ret;
}
bool FrameHashCache::SaveCacheFrame(const QString &cache_path,
const QUuid &uuid, const rational &time,
const rational &tb, FramePtr frame)
bool FrameHashCache::save_cache_frame(const QString &cache_path,
const QUuid &uuid, const Rational &time,
const Rational &tb, FramePtr frame)
{
if (cache_path.isEmpty()) {
qWarning() << "Failed to save cache frame with empty path";
return false;
}
QString fn = CachePathName(cache_path, uuid, time, tb);
QString fn = cache_path_name(cache_path, uuid, time, tb);
bool ret = SaveCacheFrame(fn, frame);
bool ret = save_cache_frame(fn, frame);
// Register frame with the disk manager
if (ret) {
QMetaObject::invokeMethod(DiskManager::instance(), "CreatedFile",
QMetaObject::invokeMethod(DiskManager::instance(), "created_file",
Q_ARG(QString, cache_path),
Q_ARG(QString, fn));
}
@@ -132,28 +132,28 @@ bool FrameHashCache::SaveCacheFrame(const QString &cache_path,
return ret;
}
FramePtr FrameHashCache::LoadCacheFrame(const QString &cache_path,
FramePtr FrameHashCache::load_cache_frame(const QString &cache_path,
const QUuid &uuid, const int64_t &time)
{
// Minor optimization, we store frames currently being saved just in case something tries to load
// while we're saving. This should *occasionally* optimize and also prevent scenarios where
// we try to load a frame that's half way through being saved.
QString filename = CachePathName(cache_path, uuid, time);
QString filename = cache_path_name(cache_path, uuid, time);
if (cache_path.isEmpty()) {
qWarning() << "Failed to load cache frame with empty path";
return nullptr;
}
return LoadCacheFrame(filename);
return load_cache_frame(filename);
}
FramePtr FrameHashCache::LoadCacheFrame(const int64_t &hash) const
FramePtr FrameHashCache::load_cache_frame(const int64_t &hash) const
{
return LoadCacheFrame(GetCacheDirectory(), GetUuid(), hash);
return load_cache_frame(get_cache_directory(), get_uuid(), hash);
}
FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
FramePtr FrameHashCache::load_cache_frame(const QString &fn)
{
FramePtr frame = nullptr;
@@ -174,23 +174,23 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
PixelFormat image_format;
if (pix_type == Imf::HALF) {
image_format = PixelFormat::F16;
image_format = PixelFormat::f16;
} else {
image_format = PixelFormat::F32;
image_format = PixelFormat::f32;
}
int channel_count = has_alpha ? VideoParams::kRGBAChannelCount :
VideoParams::kRGBChannelCount;
int channel_count = has_alpha ? VideoParams::k_rgba_channel_count :
VideoParams::k_rgb_channel_count;
frame = Frame::Create();
frame = Frame::create();
frame->set_video_params(VideoParams(
width * div, height * div, image_format, channel_count,
rational::fromDouble(file.header().pixelAspectRatio()),
VideoParams::kInterlaceNone, div));
Rational::from_double(file.header().pixelAspectRatio()),
VideoParams::k_interlace_none, div));
frame->allocate();
int bpc = VideoParams::GetBytesPerChannel(image_format);
int bpc = VideoParams::get_bytes_per_channel(image_format);
size_t xs = channel_count * bpc;
size_t ys = frame->linesize_bytes();
@@ -217,17 +217,17 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
if (img.load(fn, "jpg")) {
// FIXME: Hardcoded
const int div = 1;
const PixelFormat image_format = PixelFormat::U8;
const PixelFormat image_format = PixelFormat::u8;
const int channel_count = 4;
const rational par(1, 1);
const Rational par(1, 1);
// Convert to frame (FIXME: might be slow? may be a better way to do this on the GPU)
img.convertTo(QImage::Format_RGBA8888_Premultiplied);
frame = Frame::Create();
frame = Frame::create();
frame->set_video_params(VideoParams(
img.width() * div, img.height() * div, image_format,
channel_count, par, VideoParams::kInterlaceNone, div));
channel_count, par, VideoParams::k_interlace_none, div));
frame->allocate();
@@ -235,7 +235,7 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
memcpy(frame->data() + frame->linesize_bytes() * i,
img.bits() + img.bytesPerLine() * i,
frame->width() *
frame->video_params().GetBytesPerPixel());
frame->video_params().get_bytes_per_pixel());
}
} else {
@@ -246,7 +246,7 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
// Assume this frame is corrupt in some way and delete it
QMetaObject::invokeMethod(DiskManager::instance(),
"DeleteSpecificFile",
"delete_specific_file",
Q_ARG(QString, fn));
}
}
@@ -255,10 +255,10 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
return frame;
}
void FrameHashCache::SetPassthrough(PlaybackCache *cache)
void FrameHashCache::set_passthrough(PlaybackCache *cache)
{
super::SetPassthrough(cache);
SetTimebase(static_cast<FrameHashCache *>(cache)->GetTimebase());
super::set_passthrough(cache);
set_timebase(static_cast<FrameHashCache *>(cache)->get_timebase());
}
void FrameHashCache::LoadStateEvent(QDataStream &stream)
@@ -272,7 +272,7 @@ void FrameHashCache::LoadStateEvent(QDataStream &stream)
case 1:
stream >> num;
stream >> den;
timebase_ = rational(num, den);
timebase_ = Rational(num, den);
break;
}
}
@@ -287,60 +287,60 @@ void FrameHashCache::SaveStateEvent(QDataStream &stream)
stream << timebase_.denominator();
}
rational FrameHashCache::ToTime(const int64_t &ts) const
Rational FrameHashCache::to_time(const int64_t &ts) const
{
return Timecode::timestamp_to_time(ts, timebase_);
}
int64_t FrameHashCache::ToTimestamp(const rational &ts,
int64_t FrameHashCache::to_timestamp(const Rational &ts,
Timecode::Rounding rounding) const
{
return Timecode::time_to_timestamp(ts, timebase_, rounding);
}
void FrameHashCache::HashDeleted(const QString &path, const QString &filename)
void FrameHashCache::hash_deleted(const QString &path, const QString &filename)
{
QString cache_dir = GetCacheDirectory();
QString cache_dir = get_cache_directory();
if (cache_dir.isEmpty() || path != cache_dir) {
return;
}
QFileInfo info(filename);
if (GetUuid().toString() != info.dir().dirName()) {
if (get_uuid().toString() != info.dir().dirName()) {
return;
}
int64_t timestamp = info.fileName().toLongLong();
Invalidate(TimeRange(ToTime(timestamp), ToTime(timestamp + 1)));
invalidate(TimeRange(to_time(timestamp), to_time(timestamp + 1)));
}
void FrameHashCache::ProjectInvalidated(Project *p)
void FrameHashCache::project_invalidated(Project *p)
{
if (GetProject() == p) {
InvalidateAll();
if (get_project() == p) {
invalidate_all();
}
}
QString FrameHashCache::CachePathName(const int64_t &time) const
QString FrameHashCache::cache_path_name(const int64_t &time) const
{
return CachePathName(GetCacheDirectory(), GetUuid(), time);
return cache_path_name(get_cache_directory(), get_uuid(), time);
}
QString FrameHashCache::CachePathName(const rational &time) const
QString FrameHashCache::cache_path_name(const Rational &time) const
{
return CachePathName(GetCacheDirectory(), GetUuid(), time, timebase_);
return cache_path_name(get_cache_directory(), get_uuid(), time, timebase_);
}
QString FrameHashCache::CachePathName(const QString &cache_path,
QString FrameHashCache::cache_path_name(const QString &cache_path,
const QUuid &cache_id,
const int64_t &time)
{
QString filename = GetThisCacheDirectory(cache_path, cache_id)
QString filename = get_this_cache_directory(cache_path, cache_id)
.filePath(QString::number(time));
// Register that in some way this hash has been accessed
if (DiskManager::instance()) {
QMetaObject::invokeMethod(DiskManager::instance(), "Accessed",
QMetaObject::invokeMethod(DiskManager::instance(), "accessed",
Q_ARG(QString, cache_path),
Q_ARG(QString, filename));
}
@@ -348,29 +348,29 @@ QString FrameHashCache::CachePathName(const QString &cache_path,
return filename;
}
QString FrameHashCache::CachePathName(const QString &cache_path,
QString FrameHashCache::cache_path_name(const QString &cache_path,
const QUuid &cache_id,
const rational &time, const rational &tb)
const Rational &time, const Rational &tb)
{
return CachePathName(cache_path, cache_id,
return cache_path_name(cache_path, cache_id,
Timecode::time_to_timestamp(time, tb,
Timecode::kRound));
Timecode::k_round));
}
bool FrameHashCache::SaveCacheFrame(const QString &filename,
bool FrameHashCache::save_cache_frame(const QString &filename,
const FramePtr frame)
{
// Ensure directory is created
QDir cache_dir = QFileInfo(filename).dir();
if (!FileFunctions::DirectoryIsValid(cache_dir)) {
if (!FileFunctions::directory_is_valid(cache_dir)) {
return false;
}
if (VideoParams::FormatIsFloat(frame->format())) {
if (VideoParams::format_is_float(frame->format())) {
// Floating point types are stored in EXR
Imf::PixelType pix_type;
if (frame->format() == PixelFormat::F16) {
if (frame->format() == PixelFormat::f16) {
pix_type = Imf::HALF;
} else {
pix_type = Imf::FLOAT;
@@ -380,14 +380,14 @@ bool FrameHashCache::SaveCacheFrame(const QString &filename,
header.channels().insert("R", Imf::Channel(pix_type));
header.channels().insert("G", Imf::Channel(pix_type));
header.channels().insert("B", Imf::Channel(pix_type));
if (frame->channel_count() == VideoParams::kRGBAChannelCount) {
if (frame->channel_count() == VideoParams::k_rgba_channel_count) {
header.channels().insert("A", Imf::Channel(pix_type));
}
header.compression() = Imf::DWAA_COMPRESSION;
header.insert("dwaCompressionLevel", Imf::FloatAttribute(200.0f));
header.pixelAspectRatio() =
frame->video_params().pixel_aspect_ratio().toDouble();
frame->video_params().pixel_aspect_ratio().to_double();
header.insert("oliveDivider",
Imf::IntAttribute(frame->video_params().divider()));
@@ -395,7 +395,7 @@ bool FrameHashCache::SaveCacheFrame(const QString &filename,
try {
Imf::OutputFile out(filename.toUtf8(), header, 0);
int bpc = VideoParams::GetBytesPerChannel(frame->format());
int bpc = VideoParams::get_bytes_per_channel(frame->format());
size_t xs = frame->channel_count() * bpc;
size_t ys = frame->linesize_bytes();
@@ -407,7 +407,7 @@ bool FrameHashCache::SaveCacheFrame(const QString &filename,
xs, ys));
framebuffer.insert(
"B", Imf::Slice(pix_type, frame->data() + 2 * bpc, xs, ys));
if (frame->channel_count() == VideoParams::kRGBAChannelCount) {
if (frame->channel_count() == VideoParams::k_rgba_channel_count) {
framebuffer.insert(
"A", Imf::Slice(pix_type, frame->data() + 3 * bpc, xs, ys));
}
@@ -425,25 +425,25 @@ bool FrameHashCache::SaveCacheFrame(const QString &filename,
QImage::Format fmt = QImage::Format_Invalid;
switch (frame->format()) {
case PixelFormat::U8:
if (frame->channel_count() == VideoParams::kRGBAChannelCount) {
case PixelFormat::u8:
if (frame->channel_count() == VideoParams::k_rgba_channel_count) {
fmt = QImage::Format_RGBA8888_Premultiplied;
} else if (frame->channel_count() ==
VideoParams::kRGBChannelCount) {
VideoParams::k_rgb_channel_count) {
fmt = QImage::Format_RGB888;
}
break;
case PixelFormat::U10:
case PixelFormat::u10:
break;
case PixelFormat::U16:
if (frame->channel_count() == VideoParams::kRGBAChannelCount) {
case PixelFormat::u16:
if (frame->channel_count() == VideoParams::k_rgba_channel_count) {
fmt = QImage::Format_RGBA64_Premultiplied;
}
break;
case PixelFormat::F16:
case PixelFormat::F32:
case PixelFormat::COUNT:
case PixelFormat::INVALID:
case PixelFormat::f16:
case PixelFormat::f32:
case PixelFormat::count:
case PixelFormat::invalid:
break;
}
+32 -32
View File
@@ -19,8 +19,8 @@
***/
#ifndef VIDEORENDERFRAMECACHE_H
#define VIDEORENDERFRAMECACHE_H
#ifndef OAK_VIDEORENDERFRAMECACHE_H
#define OAK_VIDEORENDERFRAMECACHE_H
#include "codec/frame.h"
#include "render/playbackcache.h"
@@ -34,64 +34,64 @@ class FrameHashCache : public PlaybackCache {
public:
FrameHashCache(QObject *parent = nullptr);
const rational &GetTimebase() const
const Rational &get_timebase() const
{
return timebase_;
}
void SetTimebase(const rational &tb);
void set_timebase(const Rational &tb);
void ValidateTimestamp(const int64_t &ts);
void ValidateTime(const rational &time);
void validate_timestamp(const int64_t &ts);
void validate_time(const Rational &time);
bool IsFrameCached(const rational &time) const
bool is_frame_cached(const Rational &time) const
{
return GetValidatedRanges().contains(time);
return get_validated_ranges().contains(time);
}
QString GetValidCacheFilename(const rational &time) const;
QString get_valid_cache_filename(const Rational &time) const;
static bool SaveCacheFrame(const QString &filename, FramePtr frame);
bool SaveCacheFrame(const int64_t &time, FramePtr frame) const;
static bool SaveCacheFrame(const QString &cache_path, const QUuid &uuid,
static bool save_cache_frame(const QString &filename, FramePtr frame);
bool save_cache_frame(const int64_t &time, FramePtr frame) const;
static bool save_cache_frame(const QString &cache_path, const QUuid &uuid,
const int64_t &time, FramePtr frame);
static bool SaveCacheFrame(const QString &cache_path, const QUuid &uuid,
const rational &time, const rational &tb,
static bool save_cache_frame(const QString &cache_path, const QUuid &uuid,
const Rational &time, const Rational &tb,
FramePtr frame);
static FramePtr LoadCacheFrame(const QString &cache_path, const QUuid &uuid,
static FramePtr load_cache_frame(const QString &cache_path, const QUuid &uuid,
const int64_t &time);
FramePtr LoadCacheFrame(const int64_t &time) const;
static FramePtr LoadCacheFrame(const QString &fn);
FramePtr load_cache_frame(const int64_t &time) const;
static FramePtr load_cache_frame(const QString &fn);
virtual void SetPassthrough(PlaybackCache *cache) override;
virtual void set_passthrough(PlaybackCache *cache) override;
protected:
virtual void LoadStateEvent(QDataStream &stream) override;
virtual void SaveStateEvent(QDataStream &stream) override;
private:
rational ToTime(const int64_t &ts) const;
int64_t ToTimestamp(const rational &ts,
Timecode::Rounding rounding = Timecode::kRound) const;
Rational to_time(const int64_t &ts) const;
int64_t to_timestamp(const Rational &ts,
Timecode::Rounding rounding = Timecode::k_round) const;
/**
* @brief Return the path of the cached image at this time
*/
QString CachePathName(const int64_t &time) const;
QString CachePathName(const rational &time) const;
QString cache_path_name(const int64_t &time) const;
QString cache_path_name(const Rational &time) const;
static QString CachePathName(const QString &cache_path,
static QString cache_path_name(const QString &cache_path,
const QUuid &cache_id, const int64_t &time);
static QString CachePathName(const QString &cache_path,
const QUuid &cache_id, const rational &time,
const rational &tb);
static QString cache_path_name(const QString &cache_path,
const QUuid &cache_id, const Rational &time,
const Rational &tb);
rational timebase_;
Rational timebase_;
private slots:
void HashDeleted(const QString &path, const QString &filename);
void hash_deleted(const QString &path, const QString &filename);
void ProjectInvalidated(Project *p);
void project_invalidated(Project *p);
};
class ThumbnailCache : public FrameHashCache {
@@ -100,10 +100,10 @@ public:
ThumbnailCache(QObject *parent = nullptr)
: FrameHashCache(parent)
{
SetTimebase(rational(1, 10));
set_timebase(Rational(1, 10));
}
};
}
#endif // VIDEORENDERFRAMECACHE_H
#endif // OAK_VIDEORENDERFRAMECACHE_H
+13 -13
View File
@@ -28,14 +28,14 @@ namespace olive
{
FrameManager *FrameManager::instance_ = nullptr;
const int FrameManager::kFrameLifetime = 5000;
const int FrameManager::k_frame_lifetime = 5000;
void FrameManager::CreateInstance()
void FrameManager::create_instance()
{
instance_ = new FrameManager();
}
void FrameManager::DestroyInstance()
void FrameManager::destroy_instance()
{
delete instance_;
instance_ = nullptr;
@@ -46,19 +46,19 @@ FrameManager *FrameManager::instance()
return instance_;
}
char *FrameManager::Allocate(int size)
char *FrameManager::allocate(int size)
{
if (instance()) {
return instance()->AllocateFromPool(size);
return instance()->allocate_from_pool(size);
} else {
return new char[size];
}
}
void FrameManager::Deallocate(int size, char *buffer)
void FrameManager::deallocate(int size, char *buffer)
{
if (instance()) {
instance()->DeallocateToPool(size, buffer);
instance()->deallocate_to_pool(size, buffer);
} else {
delete[] buffer;
}
@@ -66,13 +66,13 @@ void FrameManager::Deallocate(int size, char *buffer)
FrameManager::FrameManager()
{
clear_timer_.setInterval(kFrameLifetime);
clear_timer_.setInterval(k_frame_lifetime);
connect(&clear_timer_, &QTimer::timeout, this,
&FrameManager::GarbageCollection);
&FrameManager::garbage_collection);
clear_timer_.start();
}
char *FrameManager::AllocateFromPool(int size)
char *FrameManager::allocate_from_pool(int size)
{
QMutexLocker locker(&mutex_);
@@ -90,7 +90,7 @@ char *FrameManager::AllocateFromPool(int size)
return buf;
}
void FrameManager::DeallocateToPool(int size, char *buffer)
void FrameManager::deallocate_to_pool(int size, char *buffer)
{
QMutexLocker locker(&mutex_);
@@ -99,11 +99,11 @@ void FrameManager::DeallocateToPool(int size, char *buffer)
buffer_list.push_back({ QDateTime::currentMSecsSinceEpoch(), buffer });
}
void FrameManager::GarbageCollection()
void FrameManager::garbage_collection()
{
QMutexLocker locker(&mutex_);
qint64 min_life = QDateTime::currentMSecsSinceEpoch() - kFrameLifetime;
qint64 min_life = QDateTime::currentMSecsSinceEpoch() - k_frame_lifetime;
for (auto it = pool_.begin(); it != pool_.end(); it++) {
std::list<Buffer> &list = it->second;
+11 -11
View File
@@ -19,8 +19,8 @@
***/
#ifndef FRAMEMANAGER_H
#define FRAMEMANAGER_H
#ifndef OAK_FRAMEMANAGER_H
#define OAK_FRAMEMANAGER_H
#include <QMutex>
#include <QObject>
@@ -32,15 +32,15 @@ namespace olive
class FrameManager : public QObject {
Q_OBJECT
public:
static void CreateInstance();
static void create_instance();
static void DestroyInstance();
static void destroy_instance();
static FrameManager *instance();
static char *Allocate(int size);
static char *allocate(int size);
static void Deallocate(int size, char *buffer);
static void deallocate(int size, char *buffer);
private:
FrameManager();
@@ -55,7 +55,7 @@ private:
*
* Thread-safe.
*/
char *AllocateFromPool(int size);
char *allocate_from_pool(int size);
/**
* @brief Deallocate buffer
@@ -65,11 +65,11 @@ private:
*
* Thread-safe.
*/
void DeallocateToPool(int size, char *buffer);
void deallocate_to_pool(int size, char *buffer);
static FrameManager *instance_;
static const int kFrameLifetime;
static const int k_frame_lifetime;
struct Buffer {
qint64 time;
@@ -83,9 +83,9 @@ private:
QTimer clear_timer_;
private slots:
void GarbageCollection();
void garbage_collection();
};
}
#endif // FRAMEMANAGER_H
#endif // OAK_FRAMEMANAGER_H
+10 -10
View File
@@ -28,30 +28,30 @@
namespace olive
{
TexturePtr Renderer::InterlaceTexture(TexturePtr top, TexturePtr bottom,
TexturePtr Renderer::interlace_texture(TexturePtr top, TexturePtr bottom,
const VideoParams &params)
{
color_cache_mutex_.lock();
if (interlace_texture_.isNull()) {
interlace_texture_ =
CreateNativeShader(ShaderCode(FileFunctions::ReadFileAsString(
create_native_shader(ShaderCode(FileFunctions::read_file_as_string(
QStringLiteral(":/shaders/interlace.frag"))));
}
color_cache_mutex_.unlock();
ShaderJob job;
job.Insert(QStringLiteral("top_tex_in"),
NodeValue(NodeValue::kTexture, QVariant::fromValue(top)));
job.Insert(QStringLiteral("bottom_tex_in"),
NodeValue(NodeValue::kTexture, QVariant::fromValue(bottom)));
job.Insert(QStringLiteral("resolution_in"),
NodeValue(NodeValue::kVec2,
job.insert(QStringLiteral("top_tex_in"),
NodeValue(NodeValue::k_texture, QVariant::fromValue(top)));
job.insert(QStringLiteral("bottom_tex_in"),
NodeValue(NodeValue::k_texture, QVariant::fromValue(bottom)));
job.insert(QStringLiteral("resolution_in"),
NodeValue(NodeValue::k_vec2,
QVector2D(params.effective_width(),
params.effective_height())));
TexturePtr output = CreateTexture(params);
TexturePtr output = create_texture(params);
BlitToTexture(interlace_texture_, job, output.get());
blit_to_texture(interlace_texture_, job, output.get());
return output;
}
+37 -37
View File
@@ -31,54 +31,54 @@ namespace
{
// Round `value` up to the next multiple of `align` (align must be a power of two).
size_t AlignUp(size_t value, size_t align)
size_t align_up(size_t value, size_t align)
{
return (value + (align - 1)) & ~(align - 1);
}
constexpr size_t kAlign = 64; // Cache-line alignment for each sub-region.
constexpr size_t k_align = 64; // Cache-line alignment for each sub-region.
} // namespace
size_t FrameSlotPool::BytesNeeded(uint32_t slot_count, size_t slot_data_bytes)
size_t FrameSlotPool::bytes_needed(uint32_t slot_count, size_t slot_data_bytes)
{
const uint32_t ring_cap = RingCapacity(slot_count);
size_t total = AlignUp(sizeof(Header), kAlign);
const uint32_t ring_cap = ring_capacity(slot_count);
size_t total = align_up(sizeof(Header), k_align);
total +=
AlignUp(SpscRingBuffer::BytesNeeded(ring_cap), kAlign); // free ring
align_up(SpscRingBuffer::bytes_needed(ring_cap), k_align); // free ring
total +=
AlignUp(SpscRingBuffer::BytesNeeded(ring_cap), kAlign); // ready ring
align_up(SpscRingBuffer::bytes_needed(ring_cap), k_align); // ready ring
total +=
AlignUp(sizeof(FrameSlotMeta) * slot_count, kAlign); // metadata array
total += AlignUp(slot_data_bytes, kAlign) * slot_count; // pixel data blocks
align_up(sizeof(FrameSlotMeta) * slot_count, k_align); // metadata array
total += align_up(slot_data_bytes, k_align) * slot_count; // pixel data blocks
return total;
}
FrameSlotPool FrameSlotPool::Create(void *mem, uint32_t slot_count,
FrameSlotPool FrameSlotPool::create(void *mem, uint32_t slot_count,
size_t slot_data_bytes)
{
FrameSlotPool pool;
pool.base_ = reinterpret_cast<uint8_t *>(mem);
const uint32_t ring_cap = RingCapacity(slot_count);
const uint32_t ring_cap = ring_capacity(slot_count);
size_t offset = 0;
const size_t header_off = offset;
offset += AlignUp(sizeof(Header), kAlign);
offset += align_up(sizeof(Header), k_align);
const size_t free_off = offset;
offset += AlignUp(SpscRingBuffer::BytesNeeded(ring_cap), kAlign);
offset += align_up(SpscRingBuffer::bytes_needed(ring_cap), k_align);
const size_t ready_off = offset;
offset += AlignUp(SpscRingBuffer::BytesNeeded(ring_cap), kAlign);
offset += align_up(SpscRingBuffer::bytes_needed(ring_cap), k_align);
const size_t meta_off = offset;
offset += AlignUp(sizeof(FrameSlotMeta) * slot_count, kAlign);
offset += align_up(sizeof(FrameSlotMeta) * slot_count, k_align);
const size_t data_off = offset;
pool.header_ = reinterpret_cast<Header *>(pool.base_ + header_off);
pool.header_->magic = kMagic;
pool.header_->magic = k_magic;
pool.header_->slot_count = slot_count;
pool.header_->slot_data_bytes = slot_data_bytes;
pool.header_->free_ring_offset = free_off;
@@ -86,8 +86,8 @@ FrameSlotPool FrameSlotPool::Create(void *mem, uint32_t slot_count,
pool.header_->meta_offset = meta_off;
pool.header_->data_offset = data_off;
pool.free_ring_ = SpscRingBuffer::Create(pool.base_ + free_off, ring_cap);
pool.ready_ring_ = SpscRingBuffer::Create(pool.base_ + ready_off, ring_cap);
pool.free_ring_ = SpscRingBuffer::create(pool.base_ + free_off, ring_cap);
pool.ready_ring_ = SpscRingBuffer::create(pool.base_ + ready_off, ring_cap);
pool.meta_ = reinterpret_cast<FrameSlotMeta *>(pool.base_ + meta_off);
pool.data_ = pool.base_ + data_off;
@@ -95,19 +95,19 @@ FrameSlotPool FrameSlotPool::Create(void *mem, uint32_t slot_count,
// Seed the free ring with every slot index so the filler can Acquire() immediately.
for (uint32_t i = 0; i < slot_count; i++) {
pool.free_ring_->Push(i);
pool.free_ring_->push(i);
}
return pool;
}
FrameSlotPool FrameSlotPool::Attach(void *mem)
FrameSlotPool FrameSlotPool::attach(void *mem)
{
FrameSlotPool pool;
pool.base_ = reinterpret_cast<uint8_t *>(mem);
pool.header_ = reinterpret_cast<Header *>(pool.base_);
if (pool.header_->magic != kMagic) {
if (pool.header_->magic != k_magic) {
// Caller will see IsValid() == false via a null header reset.
pool.header_ = nullptr;
pool.base_ = nullptr;
@@ -115,9 +115,9 @@ FrameSlotPool FrameSlotPool::Attach(void *mem)
}
pool.free_ring_ =
SpscRingBuffer::Attach(pool.base_ + pool.header_->free_ring_offset);
SpscRingBuffer::attach(pool.base_ + pool.header_->free_ring_offset);
pool.ready_ring_ =
SpscRingBuffer::Attach(pool.base_ + pool.header_->ready_ring_offset);
SpscRingBuffer::attach(pool.base_ + pool.header_->ready_ring_offset);
pool.meta_ = reinterpret_cast<FrameSlotMeta *>(pool.base_ +
pool.header_->meta_offset);
pool.data_ = pool.base_ + pool.header_->data_offset;
@@ -135,44 +135,44 @@ size_t FrameSlotPool::slot_data_bytes() const
return header_ ? size_t(header_->slot_data_bytes) : 0;
}
bool FrameSlotPool::Acquire(uint32_t *index)
bool FrameSlotPool::acquire(uint32_t *index)
{
return free_ring_->Pop(index);
return free_ring_->pop(index);
}
void *FrameSlotPool::SlotData(uint32_t index)
void *FrameSlotPool::slot_data(uint32_t index)
{
return data_ + size_t(index) * AlignUp(slot_data_bytes(), kAlign);
return data_ + size_t(index) * align_up(slot_data_bytes(), k_align);
}
const void *FrameSlotPool::SlotData(uint32_t index) const
const void *FrameSlotPool::slot_data(uint32_t index) const
{
return data_ + size_t(index) * AlignUp(slot_data_bytes(), kAlign);
return data_ + size_t(index) * align_up(slot_data_bytes(), k_align);
}
FrameSlotMeta *FrameSlotPool::Meta(uint32_t index)
FrameSlotMeta *FrameSlotPool::meta(uint32_t index)
{
return &meta_[index];
}
const FrameSlotMeta *FrameSlotPool::Meta(uint32_t index) const
const FrameSlotMeta *FrameSlotPool::meta(uint32_t index) const
{
return &meta_[index];
}
bool FrameSlotPool::Publish(uint32_t index)
bool FrameSlotPool::publish(uint32_t index)
{
return ready_ring_->Push(index);
return ready_ring_->push(index);
}
bool FrameSlotPool::Consume(uint32_t *index)
bool FrameSlotPool::consume(uint32_t *index)
{
return ready_ring_->Pop(index);
return ready_ring_->pop(index);
}
bool FrameSlotPool::Release(uint32_t index)
bool FrameSlotPool::release(uint32_t index)
{
return free_ring_->Push(index);
return free_ring_->push(index);
}
} // namespace ipc
+18 -18
View File
@@ -18,8 +18,8 @@
***/
#ifndef IPC_FRAMESLOTPOOL_H
#define IPC_FRAMESLOTPOOL_H
#ifndef OAK_IPC_FRAMESLOTPOOL_H
#define OAK_IPC_FRAMESLOTPOOL_H
#include <cstddef>
#include <cstdint>
@@ -36,7 +36,7 @@ namespace ipc
*
* Trivially-copyable POD that lives in shared memory alongside the pixel data. Carries everything
* the consumer needs to reconstruct an olive::Frame without any out-of-band information. We store
* the rational timestamp as an explicit numerator/denominator pair to stay POD (olive::rational is
* the Rational timestamp as an explicit numerator/denominator pair to stay POD (olive::Rational is
* not guaranteed shared-memory-safe).
*/
struct FrameSlotMeta {
@@ -82,7 +82,7 @@ public:
/**
* @brief Total bytes a region must provide to back a pool of `slot_count` x `slot_data_bytes`.
*/
static size_t BytesNeeded(uint32_t slot_count, size_t slot_data_bytes);
static size_t bytes_needed(uint32_t slot_count, size_t slot_data_bytes);
/**
* @brief Lay out and initialize a brand-new pool over `mem` (owner side, once).
@@ -90,7 +90,7 @@ public:
* Initializes both rings, seeds the free ring with every slot index, and zeroes metadata.
* `mem` must provide at least BytesNeeded(slot_count, slot_data_bytes) bytes.
*/
static FrameSlotPool Create(void *mem, uint32_t slot_count,
static FrameSlotPool create(void *mem, uint32_t slot_count,
size_t slot_data_bytes);
/**
@@ -98,9 +98,9 @@ public:
*
* Reads slot_count/slot_data_bytes from the in-memory header written by Create().
*/
static FrameSlotPool Attach(void *mem);
static FrameSlotPool attach(void *mem);
bool IsValid() const
bool is_valid() const
{
return header_ != nullptr;
}
@@ -113,37 +113,37 @@ public:
/**
* @brief Take ownership of a free slot. Returns false (and leaves *index untouched) if none free.
*/
bool Acquire(uint32_t *index);
bool acquire(uint32_t *index);
/**
* @brief Pointer to a slot's pixel data block (slot_data_bytes available).
*/
void *SlotData(uint32_t index);
void *slot_data(uint32_t index);
/**
* @brief Mutable metadata for a slot. Filler writes this before Publish().
*/
FrameSlotMeta *Meta(uint32_t index);
FrameSlotMeta *meta(uint32_t index);
/**
* @brief Publish a filled slot to the drainer. Must follow a successful Acquire() of `index`.
*/
bool Publish(uint32_t index);
bool publish(uint32_t index);
// ---- Drainer side ----
/**
* @brief Take the next published slot. Returns false if nothing is ready.
*/
bool Consume(uint32_t *index);
bool consume(uint32_t *index);
/**
* @brief Return a consumed slot to the free pool for reuse. Must follow Consume() of `index`.
*/
bool Release(uint32_t index);
bool release(uint32_t index);
const FrameSlotMeta *Meta(uint32_t index) const;
const void *SlotData(uint32_t index) const;
const FrameSlotMeta *meta(uint32_t index) const;
const void *slot_data(uint32_t index) const;
public:
FrameSlotPool() = default;
@@ -160,11 +160,11 @@ private:
uint64_t data_offset;
};
static constexpr uint32_t kMagic = 0x4F4B5350; // 'OKSP'
static constexpr uint32_t k_magic = 0x4F4B5350; // 'OKSP'
// Ring capacity must exceed slot_count by one because a ring can hold at most capacity-1 entries
// and we need to be able to enqueue every slot at once.
static uint32_t RingCapacity(uint32_t slot_count)
static uint32_t ring_capacity(uint32_t slot_count)
{
return slot_count + 1;
}
@@ -180,4 +180,4 @@ private:
} // namespace ipc
} // namespace olive
#endif // IPC_FRAMESLOTPOOL_H
#endif // OAK_IPC_FRAMESLOTPOOL_H
+22 -22
View File
@@ -29,14 +29,14 @@ namespace olive
namespace ipc
{
bool WriteMessage(QIODevice *device, const QJsonObject &obj)
bool write_message(QIODevice *device, const QJsonObject &obj)
{
QByteArray line = QJsonDocument(obj).toJson(QJsonDocument::Compact);
line.append('\n');
return device->write(line) == line.size();
}
bool ReadMessage(QByteArray *buffer, QJsonObject *out, bool *ok)
bool read_message(QByteArray *buffer, QJsonObject *out, bool *ok)
{
while (true) {
const int newline = buffer->indexOf('\n');
@@ -72,10 +72,10 @@ bool ReadMessage(QByteArray *buffer, QJsonObject *out, bool *ok)
// ---- HandshakeMsg ---------------------------------------------------------------------------
QJsonObject HandshakeMsg::ToJson() const
QJsonObject HandshakeMsg::to_json() const
{
QJsonObject o;
o["type"] = msgtype::kHandshake;
o["type"] = msgtype::k_handshake;
o["protocol_version"] = protocol_version;
o["shm_key"] = shm_key;
o["input_shm_key"] = input_shm_key;
@@ -86,9 +86,9 @@ QJsonObject HandshakeMsg::ToJson() const
return o;
}
bool HandshakeMsg::FromJson(const QJsonObject &o, HandshakeMsg *out)
bool HandshakeMsg::from_json(const QJsonObject &o, HandshakeMsg *out)
{
if (o["type"].toString() != QLatin1String(msgtype::kHandshake)) {
if (o["type"].toString() != QLatin1String(msgtype::k_handshake)) {
return false;
}
out->protocol_version = o["protocol_version"].toInt();
@@ -103,10 +103,10 @@ bool HandshakeMsg::FromJson(const QJsonObject &o, HandshakeMsg *out)
// ---- RenderFrameMsg -------------------------------------------------------------------------
QJsonObject RenderFrameMsg::ToJson() const
QJsonObject RenderFrameMsg::to_json() const
{
QJsonObject o;
o["type"] = msgtype::kRenderFrame;
o["type"] = msgtype::k_render_frame;
o["ticket"] = double(ticket_id);
o["node"] = node_uuid;
o["time_num"] = double(time_num);
@@ -133,9 +133,9 @@ QJsonObject RenderFrameMsg::ToJson() const
return o;
}
bool RenderFrameMsg::FromJson(const QJsonObject &o, RenderFrameMsg *out)
bool RenderFrameMsg::from_json(const QJsonObject &o, RenderFrameMsg *out)
{
if (o["type"].toString() != QLatin1String(msgtype::kRenderFrame)) {
if (o["type"].toString() != QLatin1String(msgtype::k_render_frame)) {
return false;
}
out->ticket_id = qint64(o["ticket"].toDouble());
@@ -169,18 +169,18 @@ bool RenderFrameMsg::FromJson(const QJsonObject &o, RenderFrameMsg *out)
// ---- FrameReadyMsg --------------------------------------------------------------------------
QJsonObject FrameReadyMsg::ToJson() const
QJsonObject FrameReadyMsg::to_json() const
{
QJsonObject o;
o["type"] = msgtype::kFrameReady;
o["type"] = msgtype::k_frame_ready;
o["ticket"] = double(ticket_id);
o["slot"] = output_slot;
return o;
}
bool FrameReadyMsg::FromJson(const QJsonObject &o, FrameReadyMsg *out)
bool FrameReadyMsg::from_json(const QJsonObject &o, FrameReadyMsg *out)
{
if (o["type"].toString() != QLatin1String(msgtype::kFrameReady)) {
if (o["type"].toString() != QLatin1String(msgtype::k_frame_ready)) {
return false;
}
out->ticket_id = qint64(o["ticket"].toDouble());
@@ -190,17 +190,17 @@ bool FrameReadyMsg::FromJson(const QJsonObject &o, FrameReadyMsg *out)
// ---- CancelMsg ------------------------------------------------------------------------------
QJsonObject CancelMsg::ToJson() const
QJsonObject CancelMsg::to_json() const
{
QJsonObject o;
o["type"] = msgtype::kCancel;
o["type"] = msgtype::k_cancel;
o["ticket"] = double(ticket_id);
return o;
}
bool CancelMsg::FromJson(const QJsonObject &o, CancelMsg *out)
bool CancelMsg::from_json(const QJsonObject &o, CancelMsg *out)
{
if (o["type"].toString() != QLatin1String(msgtype::kCancel)) {
if (o["type"].toString() != QLatin1String(msgtype::k_cancel)) {
return false;
}
out->ticket_id = qint64(o["ticket"].toDouble());
@@ -209,17 +209,17 @@ bool CancelMsg::FromJson(const QJsonObject &o, CancelMsg *out)
// ---- LoadGraphMsg ---------------------------------------------------------------------------
QJsonObject LoadGraphMsg::ToJson() const
QJsonObject LoadGraphMsg::to_json() const
{
QJsonObject o;
o["type"] = msgtype::kLoadGraph;
o["type"] = msgtype::k_load_graph;
o["path"] = path;
return o;
}
bool LoadGraphMsg::FromJson(const QJsonObject &o, LoadGraphMsg *out)
bool LoadGraphMsg::from_json(const QJsonObject &o, LoadGraphMsg *out)
{
if (o["type"].toString() != QLatin1String(msgtype::kLoadGraph)) {
if (o["type"].toString() != QLatin1String(msgtype::k_load_graph)) {
return false;
}
out->path = o["path"].toString();
+23 -23
View File
@@ -18,8 +18,8 @@
***/
#ifndef IPC_IPCMESSAGE_H
#define IPC_IPCMESSAGE_H
#ifndef OAK_IPC_IPCMESSAGE_H
#define OAK_IPC_IPCMESSAGE_H
#include <cstdint>
#include <QByteArray>
@@ -55,14 +55,14 @@ namespace ipc
*/
namespace msgtype
{
constexpr const char *kHandshake = "handshake";
constexpr const char *kLoadGraph = "load_graph";
constexpr const char *kRenderFrame = "render_frame";
constexpr const char *kFrameReady = "frame_ready";
constexpr const char *kCancel = "cancel";
constexpr const char *kGraphUpdate = "graph_update";
constexpr const char *kShutdown = "shutdown";
constexpr const char *kError = "error";
constexpr const char *k_handshake = "handshake";
constexpr const char *k_load_graph = "load_graph";
constexpr const char *k_render_frame = "render_frame";
constexpr const char *k_frame_ready = "frame_ready";
constexpr const char *k_cancel = "cancel";
constexpr const char *k_graph_update = "graph_update";
constexpr const char *k_shutdown = "shutdown";
constexpr const char *k_error = "error";
} // namespace msgtype
/**
@@ -71,7 +71,7 @@ constexpr const char *kError = "error";
* Serializes `obj` to compact JSON, appends '\n', and writes the whole line in one call. Returns
* true only if the full line was written.
*/
bool WriteMessage(QIODevice *device, const QJsonObject &obj);
bool write_message(QIODevice *device, const QJsonObject &obj);
/**
* @brief Pull one complete NDJSON line out of `buffer` and parse it.
@@ -82,7 +82,7 @@ bool WriteMessage(QIODevice *device, const QJsonObject &obj);
* and continue rather than wedge. Supports the typical "append bytes as they arrive, then drain
* complete lines" reader loop on a pipe.
*/
bool ReadMessage(QByteArray *buffer, QJsonObject *out, bool *ok = nullptr);
bool read_message(QByteArray *buffer, QJsonObject *out, bool *ok = nullptr);
// ---- Typed message builders / parsers -------------------------------------------------------
//
@@ -100,8 +100,8 @@ struct HandshakeMsg {
qint64 slot_data_bytes = 0; ///< Per-output-slot pixel block size.
qint64 input_slot_data_bytes = 0; ///< Per-input-slot pixel block size.
QJsonObject ToJson() const;
static bool FromJson(const QJsonObject &o, HandshakeMsg *out);
QJsonObject to_json() const;
static bool from_json(const QJsonObject &o, HandshakeMsg *out);
};
struct RenderFrameMsg {
@@ -129,33 +129,33 @@ struct RenderFrameMsg {
QString color_view;
QString color_look;
QJsonObject ToJson() const;
static bool FromJson(const QJsonObject &o, RenderFrameMsg *out);
QJsonObject to_json() const;
static bool from_json(const QJsonObject &o, RenderFrameMsg *out);
};
struct FrameReadyMsg {
qint64 ticket_id = 0;
int output_slot = 0; ///< Index into the worker->main output FrameSlotPool.
QJsonObject ToJson() const;
static bool FromJson(const QJsonObject &o, FrameReadyMsg *out);
QJsonObject to_json() const;
static bool from_json(const QJsonObject &o, FrameReadyMsg *out);
};
struct CancelMsg {
qint64 ticket_id = 0;
QJsonObject ToJson() const;
static bool FromJson(const QJsonObject &o, CancelMsg *out);
QJsonObject to_json() const;
static bool from_json(const QJsonObject &o, CancelMsg *out);
};
struct LoadGraphMsg {
QString path; ///< Temporary file holding the serialized node graph.
QJsonObject ToJson() const;
static bool FromJson(const QJsonObject &o, LoadGraphMsg *out);
QJsonObject to_json() const;
static bool from_json(const QJsonObject &o, LoadGraphMsg *out);
};
} // namespace ipc
} // namespace olive
#endif // IPC_IPCMESSAGE_H
#endif // OAK_IPC_IPCMESSAGE_H
+11 -11
View File
@@ -41,7 +41,7 @@ namespace ipc
SharedMemoryRegion::SharedMemoryRegion()
: size_(0)
, data_(nullptr)
, mode_(kAttach)
, mode_(k_attach)
#if defined(Q_OS_WIN)
, handle_(nullptr)
#else
@@ -52,10 +52,10 @@ SharedMemoryRegion::SharedMemoryRegion()
SharedMemoryRegion::~SharedMemoryRegion()
{
Close();
close();
}
QString SharedMemoryRegion::MakeKey(qint64 owner_pid, int worker_index)
QString SharedMemoryRegion::make_key(qint64 owner_pid, int worker_index)
{
return QStringLiteral("olive-rw-%1-%2").arg(owner_pid).arg(worker_index);
}
@@ -131,9 +131,9 @@ void SharedMemoryRegion::Close()
#else // POSIX
bool SharedMemoryRegion::Open(const QString &key, size_t size, Mode mode)
bool SharedMemoryRegion::open(const QString &key, size_t size, Mode mode)
{
Close();
close();
key_ = key;
size_ = size;
@@ -144,7 +144,7 @@ bool SharedMemoryRegion::Open(const QString &key, size_t size, Mode mode)
const QByteArray name_bytes = shm_name_.toUtf8();
int oflag = O_RDWR;
if (mode == kCreate) {
if (mode == k_create) {
oflag |= O_CREAT | O_EXCL;
// Clear any stale segment left by a crashed previous run with the same name.
shm_unlink(name_bytes.constData());
@@ -157,7 +157,7 @@ bool SharedMemoryRegion::Open(const QString &key, size_t size, Mode mode)
return false;
}
if (mode == kCreate) {
if (mode == k_create) {
if (ftruncate(fd_, off_t(size)) != 0) {
error_ = QStringLiteral("ftruncate failed: %1")
.arg(QString::fromUtf8(strerror(errno)));
@@ -195,19 +195,19 @@ bool SharedMemoryRegion::Open(const QString &key, size_t size, Mode mode)
data_ = nullptr;
::close(fd_);
fd_ = -1;
if (mode == kCreate) {
if (mode == k_create) {
shm_unlink(name_bytes.constData());
}
return false;
}
if (mode == kCreate) {
if (mode == k_create) {
memset(data_, 0, size);
}
return true;
}
void SharedMemoryRegion::Close()
void SharedMemoryRegion::close()
{
if (data_) {
munmap(data_, size_);
@@ -217,7 +217,7 @@ void SharedMemoryRegion::Close()
::close(fd_);
fd_ = -1;
}
if (mode_ == kCreate && !shm_name_.isEmpty()) {
if (mode_ == k_create && !shm_name_.isEmpty()) {
// Only the owner unlinks, so the name is freed once both sides have unmapped.
shm_unlink(shm_name_.toUtf8().constData());
shm_name_.clear();
+9 -9
View File
@@ -18,8 +18,8 @@
***/
#ifndef IPC_SHAREDMEMORYREGION_H
#define IPC_SHAREDMEMORYREGION_H
#ifndef OAK_IPC_SHAREDMEMORYREGION_H
#define OAK_IPC_SHAREDMEMORYREGION_H
#include <cstddef>
#include <QString>
@@ -46,9 +46,9 @@ class SharedMemoryRegion {
public:
enum Mode {
/// Create (and own) the segment. Fails if it already exists; unlinks on destruction.
kCreate,
k_create,
/// Attach to a segment created by the peer. Does not unlink on destruction.
kAttach
k_attach
};
SharedMemoryRegion();
@@ -63,14 +63,14 @@ public:
* `key` is a short identifier (no leading slash needed; the platform prefix is added internally).
* Returns true on success. On failure, error() carries a human-readable reason.
*/
bool Open(const QString &key, size_t size, Mode mode);
bool open(const QString &key, size_t size, Mode mode);
/**
* @brief Unmap and (if owner) unlink the segment. Called automatically by the destructor.
*/
void Close();
void close();
bool IsValid() const
bool is_valid() const
{
return data_ != nullptr;
}
@@ -100,7 +100,7 @@ public:
*
* Centralized so the owner and the spawned worker agree on the same name.
*/
static QString MakeKey(qint64 owner_pid, int worker_index);
static QString make_key(qint64 owner_pid, int worker_index);
private:
QString key_;
@@ -120,4 +120,4 @@ private:
} // namespace ipc
} // namespace olive
#endif // IPC_SHAREDMEMORYREGION_H
#endif // OAK_IPC_SHAREDMEMORYREGION_H
+13 -13
View File
@@ -18,8 +18,8 @@
***/
#ifndef IPC_SPSCRINGBUFFER_H
#define IPC_SPSCRINGBUFFER_H
#ifndef OAK_IPC_SPSCRINGBUFFER_H
#define OAK_IPC_SPSCRINGBUFFER_H
#include <atomic>
#include <cstddef>
@@ -60,7 +60,7 @@ public:
* intended to be placement-style initialization performed exactly once by whichever process owns
* the segment's creation; the peer process uses Attach() instead.
*/
static SpscRingBuffer *Create(void *mem, uint32_t capacity)
static SpscRingBuffer *create(void *mem, uint32_t capacity)
{
auto *self = reinterpret_cast<SpscRingBuffer *>(mem);
self->capacity_ = capacity;
@@ -77,7 +77,7 @@ public:
*
* No writes are performed; the cursors and capacity are assumed already set by Create().
*/
static SpscRingBuffer *Attach(void *mem)
static SpscRingBuffer *attach(void *mem)
{
return reinterpret_cast<SpscRingBuffer *>(mem);
}
@@ -85,7 +85,7 @@ public:
/**
* @brief Total bytes required to hold the header plus `capacity` index slots.
*/
static size_t BytesNeeded(uint32_t capacity)
static size_t bytes_needed(uint32_t capacity)
{
return sizeof(SpscRingBuffer) + size_t(capacity) * sizeof(uint32_t);
}
@@ -93,10 +93,10 @@ public:
/**
* @brief Producer side: enqueue an index. Returns false if the buffer is full.
*/
bool Push(uint32_t value)
bool push(uint32_t value)
{
const uint32_t head = head_.load(std::memory_order_relaxed);
const uint32_t next = Increment(head);
const uint32_t next = increment(head);
// Buffer is full if advancing head would collide with the consumer's tail.
if (next == tail_.load(std::memory_order_acquire)) {
@@ -111,7 +111,7 @@ public:
/**
* @brief Consumer side: dequeue an index into `out`. Returns false if the buffer is empty.
*/
bool Pop(uint32_t *out)
bool pop(uint32_t *out)
{
const uint32_t tail = tail_.load(std::memory_order_relaxed);
@@ -121,7 +121,7 @@ public:
}
*out = slot_array()[tail];
tail_.store(Increment(tail), std::memory_order_release);
tail_.store(increment(tail), std::memory_order_release);
return true;
}
@@ -131,14 +131,14 @@ public:
* Safe to call from either side, but the value may be stale the instant it returns. Intended for
* metrics/backpressure heuristics, not for correctness decisions.
*/
uint32_t SizeApprox() const
uint32_t size_approx() const
{
const uint32_t head = head_.load(std::memory_order_acquire);
const uint32_t tail = tail_.load(std::memory_order_acquire);
return (head + capacity_ - tail) % capacity_;
}
bool IsEmptyApprox() const
bool is_empty_approx() const
{
return head_.load(std::memory_order_acquire) ==
tail_.load(std::memory_order_acquire);
@@ -150,7 +150,7 @@ public:
}
private:
uint32_t Increment(uint32_t index) const
uint32_t increment(uint32_t index) const
{
// capacity_ is small and this avoids requiring a power-of-two capacity.
return (index + 1) % capacity_;
@@ -182,4 +182,4 @@ private:
} // namespace ipc
} // namespace olive
#endif // IPC_SPSCRINGBUFFER_H
#endif // OAK_IPC_SPSCRINGBUFFER_H
+9 -9
View File
@@ -19,8 +19,8 @@
***/
#ifndef ACCELERATEDJOB_H
#define ACCELERATEDJOB_H
#ifndef OAK_ACCELERATEDJOB_H
#define OAK_ACCELERATEDJOB_H
#include "node/param.h"
#include "node/valuedatabase.h"
@@ -36,22 +36,22 @@ public:
{
}
virtual NodeValue Get(const QString &input) const
virtual NodeValue get(const QString &input) const
{
return value_map_.value(input);
}
virtual void Insert(const QString &input, const NodeValueRow &row)
virtual void insert(const QString &input, const NodeValueRow &row)
{
value_map_.insert(input, row.value(input));
}
virtual void Insert(const QString &input, const NodeValue &value)
virtual void insert(const QString &input, const NodeValue &value)
{
value_map_.insert(input, value);
}
virtual void Insert(const NodeValueRow &row)
virtual void insert(const NodeValueRow &row)
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
value_map_.insert(row);
@@ -62,11 +62,11 @@ public:
#endif
}
virtual const NodeValueRow &GetValues() const
virtual const NodeValueRow &get_values() const
{
return value_map_;
}
virtual NodeValueRow &GetValues()
virtual NodeValueRow &get_values()
{
return value_map_;
}
@@ -77,4 +77,4 @@ protected:
}
#endif // ACCELERATEDJOB_H
#endif // OAK_ACCELERATEDJOB_H
+7 -7
View File
@@ -19,8 +19,8 @@
***/
#ifndef CACHEJOB_H
#define CACHEJOB_H
#ifndef OAK_CACHEJOB_H
#define OAK_CACHEJOB_H
#include <QString>
#include <QVariant>
@@ -39,20 +39,20 @@ public:
filename_ = filename;
}
const QString &GetFilename() const
const QString &get_filename() const
{
return filename_;
}
void SetFilename(const QString &s)
void set_filename(const QString &s)
{
filename_ = s;
}
const NodeValue &GetFallback() const
const NodeValue &get_fallback() const
{
return fallback_;
}
void SetFallback(const NodeValue &val)
void set_fallback(const NodeValue &val)
{
fallback_ = val;
}
@@ -65,4 +65,4 @@ private:
}
#endif // CACHEJOB_H
#endif // OAK_CACHEJOB_H
+28 -28
View File
@@ -19,8 +19,8 @@
***/
#ifndef COLORTRANSFORMJOB_H
#define COLORTRANSFORMJOB_H
#ifndef OAK_COLORTRANSFORMJOB_H
#define OAK_COLORTRANSFORMJOB_H
#include <QMatrix4x4>
#include <QString>
@@ -41,7 +41,7 @@ public:
{
processor_ = nullptr;
custom_shader_src_ = nullptr;
input_alpha_association_ = kAlphaNone;
input_alpha_association_ = k_alpha_none;
clear_destination_ = true;
force_opaque_ = false;
}
@@ -49,7 +49,7 @@ public:
ColorTransformJob(const NodeValueRow &row)
: ColorTransformJob()
{
Insert(row);
insert(row);
}
QString id() const
@@ -61,98 +61,98 @@ public:
}
}
void SetOverrideID(const QString &id)
void set_override_id(const QString &id)
{
id_ = id;
}
const NodeValue &GetInputTexture() const
const NodeValue &get_input_texture() const
{
return input_texture_;
}
void SetInputTexture(const NodeValue &tex)
void set_input_texture(const NodeValue &tex)
{
input_texture_ = tex;
}
void SetInputTexture(TexturePtr tex)
void set_input_texture(TexturePtr tex)
{
Q_ASSERT(!tex->IsDummy());
input_texture_ = NodeValue(NodeValue::kTexture, tex);
Q_ASSERT(!tex->is_dummy());
input_texture_ = NodeValue(NodeValue::k_texture, tex);
}
ColorProcessorPtr GetColorProcessor() const
ColorProcessorPtr get_color_processor() const
{
return processor_;
}
void SetColorProcessor(ColorProcessorPtr p)
void set_color_processor(ColorProcessorPtr p)
{
processor_ = p;
}
const AlphaAssociated &GetInputAlphaAssociation() const
const AlphaAssociated &get_input_alpha_association() const
{
return input_alpha_association_;
}
void SetInputAlphaAssociation(const AlphaAssociated &e)
void set_input_alpha_association(const AlphaAssociated &e)
{
input_alpha_association_ = e;
}
const Node *CustomShaderSource() const
const Node *custom_shader_source() const
{
return custom_shader_src_;
}
const QString &CustomShaderID() const
const QString &custom_shader_id() const
{
return custom_shader_id_;
}
void SetNeedsCustomShader(const Node *node, const QString &id = QString())
void set_needs_custom_shader(const Node *node, const QString &id = QString())
{
custom_shader_src_ = node;
custom_shader_id_ = id;
}
bool IsClearDestinationEnabled() const
bool is_clear_destination_enabled() const
{
return clear_destination_;
}
void SetClearDestinationEnabled(bool e)
void set_clear_destination_enabled(bool e)
{
clear_destination_ = e;
}
const QMatrix4x4 &GetTransformMatrix() const
const QMatrix4x4 &get_transform_matrix() const
{
return matrix_;
}
void SetTransformMatrix(const QMatrix4x4 &m)
void set_transform_matrix(const QMatrix4x4 &m)
{
matrix_ = m;
}
const QMatrix4x4 &GetCropMatrix() const
const QMatrix4x4 &get_crop_matrix() const
{
return crop_matrix_;
}
void SetCropMatrix(const QMatrix4x4 &m)
void set_crop_matrix(const QMatrix4x4 &m)
{
crop_matrix_ = m;
}
const QString &GetFunctionName() const
const QString &get_function_name() const
{
return function_name_;
}
void SetFunctionName(const QString &function_name = QString())
void set_function_name(const QString &function_name = QString())
{
function_name_ = function_name;
};
bool GetForceOpaque() const
bool get_force_opaque() const
{
return force_opaque_;
}
void SetForceOpaque(bool e)
void set_force_opaque(bool e)
{
force_opaque_ = e;
}
@@ -181,4 +181,4 @@ private:
}
#endif // COLORTRANSFORMJOB_H
#endif // OAK_COLORTRANSFORMJOB_H
+8 -8
View File
@@ -19,8 +19,8 @@
***/
#ifndef FOOTAGEJOB_H
#define FOOTAGEJOB_H
#ifndef OAK_FOOTAGEJOB_H
#define OAK_FOOTAGEJOB_H
#include "node/project/footage/footage.h"
@@ -30,13 +30,13 @@ namespace olive
class FootageJob : public AcceleratedJob {
public:
FootageJob()
: type_(Track::kNone)
: type_(Track::k_none)
{
}
FootageJob(const TimeRange &time, const QString &decoder,
const QString &filename, Track::Type type,
const rational &length, LoopMode loop_mode)
const Rational &length, LoopMode loop_mode)
: time_(time)
, decoder_(decoder)
, filename_(filename)
@@ -120,12 +120,12 @@ public:
cache_path_ = p;
}
const rational &length() const
const Rational &length() const
{
return length_;
}
void set_length(const rational &length)
void set_length(const Rational &length)
{
length_ = length;
}
@@ -167,7 +167,7 @@ private:
QString cache_path_;
rational length_;
Rational length_;
LoopMode loop_mode_;
};
@@ -176,4 +176,4 @@ private:
Q_DECLARE_METATYPE(olive::FootageJob)
#endif // FOOTAGEJOB_H
#endif // OAK_FOOTAGEJOB_H
+4 -4
View File
@@ -19,8 +19,8 @@
***/
#ifndef GENERATEJOB_H
#define GENERATEJOB_H
#ifndef OAK_GENERATEJOB_H
#define OAK_GENERATEJOB_H
#include "acceleratedjob.h"
#include "codec/frame.h"
@@ -34,10 +34,10 @@ public:
GenerateJob(const NodeValueRow &row)
: GenerateJob()
{
Insert(row);
insert(row);
}
};
}
#endif // GENERATEJOB_H
#endif // OAK_GENERATEJOB_H
+14 -14
View File
@@ -17,10 +17,10 @@
*
*/
#ifndef PLUGINJOB_H
#define PLUGINJOB_H
#ifndef OAK_PLUGINJOB_H
#define OAK_PLUGINJOB_H
#include "acceleratedjob.h"
#include "pluginSupport/OlivePluginInstance.h"
#include "pluginSupport/oliveplugininstance.h"
#include "olive/core/util/rational.h"
#include <any>
@@ -33,19 +33,19 @@ namespace plugin
class PluginJob : public AcceleratedJob {
public:
explicit PluginJob(const OFX::Host::ImageEffect::Instance *pluginInstance,
explicit PluginJob(const OFX::Host::ImageEffect::Instance *plugin_instance,
const PluginNode *node, NodeValueRow row,
const olive::core::rational &time)
const olive::core::Rational &time)
: AcceleratedJob()
, time_seconds_(time.toDouble())
, time_seconds_(time.to_double())
{
this->pluginInstance_ = pluginInstance;
this->pluginInstance_ = plugin_instance;
this->node_ = node;
Insert(row);
insert(row);
}
explicit PluginJob(const OFX::Host::ImageEffect::Instance *pluginInstance,
explicit PluginJob(const OFX::Host::ImageEffect::Instance *plugin_instance,
const PluginNode *node, NodeValueRow row)
: PluginJob(pluginInstance, node, row, olive::core::rational(0))
: PluginJob(plugin_instance, node, row, olive::core::Rational(0))
{
}
@@ -54,7 +54,7 @@ public:
return const_cast<PluginNode *>(node_);
}
OFX::Host::ImageEffect::Instance *pluginInstance()
OFX::Host::ImageEffect::Instance *plugin_instance()
{
return const_cast<OFX::Host::ImageEffect::Instance *>(pluginInstance_);
}
@@ -67,9 +67,9 @@ public:
private:
const OFX::Host::ImageEffect::Instance *pluginInstance_ = nullptr;
QHash<OfxTime, QHash<QString, std::any>> paramsOnTime;
QHash<OfxTime, QHash<QString, std::any>> paramsOnTime_;
QHash<QString, std::any> params;
QHash<QString, std::any> params_;
const PluginNode *node_ = nullptr;
double time_seconds_ = 0.0;
@@ -78,4 +78,4 @@ private:
} // plugin
} // olive
#endif //PLUGINJOB_H
#endif //OAK_PLUGINJOB_H
+6 -6
View File
@@ -19,8 +19,8 @@
***/
#ifndef SAMPLEJOB_H
#define SAMPLEJOB_H
#ifndef OAK_SAMPLEJOB_H
#define OAK_SAMPLEJOB_H
#include "acceleratedjob.h"
@@ -35,14 +35,14 @@ public:
SampleJob(const TimeRange &time, const NodeValue &value)
{
samples_ = value.toSamples();
samples_ = value.to_samples();
time_ = time;
}
SampleJob(const TimeRange &time, const QString &from,
const NodeValueRow &row)
{
samples_ = row[from].toSamples();
samples_ = row[from].to_samples();
time_ = time;
}
@@ -51,7 +51,7 @@ public:
return samples_;
}
bool HasSamples() const
bool has_samples() const
{
return samples_.is_allocated();
}
@@ -71,4 +71,4 @@ private:
Q_DECLARE_METATYPE(olive::SampleJob)
#endif // SAMPLEJOB_H
#endif // OAK_SAMPLEJOB_H
+18 -18
View File
@@ -19,8 +19,8 @@
***/
#ifndef SHADERJOB_H
#define SHADERJOB_H
#ifndef OAK_SHADERJOB_H
#define OAK_SHADERJOB_H
#include <QMatrix4x4>
#include <QVector>
@@ -42,66 +42,66 @@ public:
ShaderJob(const NodeValueRow &row)
: ShaderJob()
{
Insert(row);
insert(row);
}
const QString &GetShaderID() const
const QString &get_shader_id() const
{
return shader_id_;
}
void SetShaderID(const QString &id)
void set_shader_id(const QString &id)
{
shader_id_ = id;
}
void SetIterations(int iterations, const NodeInput &iterative_input)
void set_iterations(int iterations, const NodeInput &iterative_input)
{
SetIterations(iterations, iterative_input.input());
set_iterations(iterations, iterative_input.input());
}
void SetIterations(int iterations, const QString &iterative_input)
void set_iterations(int iterations, const QString &iterative_input)
{
iterations_ = iterations;
iterative_input_ = iterative_input;
}
int GetIterationCount() const
int get_iteration_count() const
{
return iterations_;
}
const QString &GetIterativeInput() const
const QString &get_iterative_input() const
{
return iterative_input_;
}
Texture::Interpolation GetInterpolation(const QString &id) const
Texture::Interpolation get_interpolation(const QString &id) const
{
return interpolation_.value(id, Texture::kDefaultInterpolation);
return interpolation_.value(id, Texture::k_default_interpolation);
}
const QHash<QString, Texture::Interpolation> &GetInterpolationMap() const
const QHash<QString, Texture::Interpolation> &get_interpolation_map() const
{
return interpolation_;
}
void SetInterpolation(const NodeInput &input, Texture::Interpolation interp)
void set_interpolation(const NodeInput &input, Texture::Interpolation interp)
{
interpolation_.insert(input.input(), interp);
}
void SetInterpolation(const QString &id, Texture::Interpolation interp)
void set_interpolation(const QString &id, Texture::Interpolation interp)
{
interpolation_.insert(id, interp);
}
void SetVertexCoordinates(const QVector<float> &vertex_coords)
void set_vertex_coordinates(const QVector<float> &vertex_coords)
{
vertex_overrides_ = vertex_coords;
}
const QVector<float> &GetVertexCoordinates()
const QVector<float> &get_vertex_coordinates()
{
return vertex_overrides_;
}
@@ -120,4 +120,4 @@ private:
}
#endif // SHADERJOB_H
#endif // OAK_SHADERJOB_H
+4 -4
View File
@@ -16,14 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LOOPMODE_H
#define LOOPMODE_H
#ifndef OAK_LOOPMODE_H
#define OAK_LOOPMODE_H
namespace olive
{
enum class LoopMode { kLoopModeOff, kLoopModeLoop, kLoopModeClamp };
enum class LoopMode { k_loop_mode_off, k_loop_mode_loop, k_loop_mode_clamp };
}
#endif // LOOPMODE_H
#endif // OAK_LOOPMODE_H
+9 -9
View File
@@ -29,7 +29,7 @@
namespace olive
{
bool LUTLibrary::IsSupportedExtension(const QString &suffix)
bool LUTLibrary::is_supported_extension(const QString &suffix)
{
QString s = suffix;
if (s.startsWith(QLatin1Char('.'))) {
@@ -40,9 +40,9 @@ bool LUTLibrary::IsSupportedExtension(const QString &suffix)
return lower == QStringLiteral("cube") || lower == QStringLiteral("3dl");
}
QStringList LUTLibrary::GetDirectories()
QStringList LUTLibrary::get_directories()
{
const QString serialized = OLIVE_CONFIG("LUTLibraryPaths").toString();
const QString serialized = OAK_CONFIG("LUTLibraryPaths").toString();
QStringList dirs = serialized.split(QLatin1Char(';'), Qt::SkipEmptyParts);
for (QString &dir : dirs) {
@@ -51,7 +51,7 @@ QStringList LUTLibrary::GetDirectories()
return dirs;
}
void LUTLibrary::SetDirectories(const QStringList &dirs)
void LUTLibrary::set_directories(const QStringList &dirs)
{
QStringList cleaned;
for (const QString &dir : dirs) {
@@ -61,19 +61,19 @@ void LUTLibrary::SetDirectories(const QStringList &dirs)
}
}
Config::Current()[QStringLiteral("LUTLibraryPaths")] =
Config::current()[QStringLiteral("LUTLibraryPaths")] =
cleaned.join(QLatin1Char(';'));
}
QStringList LUTLibrary::GetLutFiles()
QStringList LUTLibrary::get_lut_files()
{
QStringList files;
static const QStringList kFilters = { QStringLiteral("*.cube"),
static const QStringList k_filters = { QStringLiteral("*.cube"),
QStringLiteral("*.3dl") };
for (const QString &dir : GetDirectories()) {
QDirIterator it(dir, kFilters, QDir::Files,
for (const QString &dir : get_directories()) {
QDirIterator it(dir, k_filters, QDir::Files,
QDirIterator::Subdirectories);
while (it.hasNext()) {
files.append(it.next());
+7 -7
View File
@@ -18,8 +18,8 @@
***/
#ifndef LUTLIBRARY_H
#define LUTLIBRARY_H
#ifndef OAK_LUTLIBRARY_H
#define OAK_LUTLIBRARY_H
#include <QString>
#include <QStringList>
@@ -41,18 +41,18 @@ public:
* @brief Returns true if the given file suffix is a supported LUT
* extension (.cube or .3dl, case-insensitive, leading dot tolerated)
*/
static bool IsSupportedExtension(const QString &suffix);
static bool is_supported_extension(const QString &suffix);
/**
* @brief The directories that make up the LUT library
*/
static QStringList GetDirectories();
static QStringList get_directories();
/**
* @brief Replaces the LUT library directories and saves them to the
* application config
*/
static void SetDirectories(const QStringList &dirs);
static void set_directories(const QStringList &dirs);
/**
* @brief All supported LUT files found under the library directories
@@ -60,9 +60,9 @@ public:
* Directories are scanned recursively. Files in earlier directories
* are listed first.
*/
static QStringList GetLutFiles();
static QStringList get_lut_files();
};
}
#endif // LUTLIBRARY_H
#endif // OAK_LUTLIBRARY_H
+3 -3
View File
@@ -19,8 +19,8 @@
***/
#ifndef MANAGEDCOLOR_H
#define MANAGEDCOLOR_H
#ifndef OAK_MANAGEDCOLOR_H
#define OAK_MANAGEDCOLOR_H
#include <olive/core/core.h>
@@ -52,4 +52,4 @@ private:
}
#endif // MANAGEDCOLOR_H
#endif // OAK_MANAGEDCOLOR_H
+34 -34
View File
@@ -16,23 +16,23 @@ namespace
class BackendOpenGLRenderer : public olive::OpenGLRenderer {
public:
using olive::OpenGLRenderer::OpenGLRenderer;
using olive::OpenGLRenderer::Blit;
using olive::OpenGLRenderer::CreateNativeTexture;
using olive::OpenGLRenderer::DestroyInternal;
using olive::OpenGLRenderer::DestroyNativeTexture;
using olive::OpenGLRenderer::AttachTextureAsDestination;
using olive::OpenGLRenderer::DetachTextureAsDestination;
using olive::OpenGLRenderer::blit;
using olive::OpenGLRenderer::create_native_texture;
using olive::OpenGLRenderer::destroy_internal;
using olive::OpenGLRenderer::destroy_native_texture;
using olive::OpenGLRenderer::attach_texture_as_destination;
using olive::OpenGLRenderer::detach_texture_as_destination;
};
// Converts the opaque C ABI handle back to the C++ renderer used internally.
BackendOpenGLRenderer *Renderer(OakRenderBackendHandle handle)
BackendOpenGLRenderer *renderer(OakRenderBackendHandle handle)
{
return static_cast<BackendOpenGLRenderer *>(handle);
}
// Interprets ABI QVariant payloads without copying; both modules are built
// against the same Qt/C++ ABI in this first-generation dynamic backend.
const QVariant &VariantRef(const void *variant)
const QVariant &variant_ref(const void *variant)
{
return *static_cast<const QVariant *>(variant);
}
@@ -50,7 +50,7 @@ oak_renderer_create(void *parent)
OAK_RENDER_BACKEND_EXPORT void
oak_renderer_destroy(OakRenderBackendHandle handle)
{
delete Renderer(handle);
delete renderer(handle);
}
// Reports static OpenGL backend capabilities to the adapter.
@@ -62,11 +62,11 @@ oak_renderer_get_info(OakRenderBackendHandle handle,
return false;
}
out_info->abi_version = 1;
out_info->kind = OAK_RENDER_BACKEND_OPENGL;
out_info->kind = oak_render_backend_opengl;
out_info->capabilities =
OAK_RENDER_BACKEND_CAP_TEXTURES | OAK_RENDER_BACKEND_CAP_SHADERS |
OAK_RENDER_BACKEND_CAP_BLIT | OAK_RENDER_BACKEND_CAP_READBACK |
OAK_RENDER_BACKEND_CAP_VIEWER_CONTEXT;
oak_render_backend_cap_textures | oak_render_backend_cap_shaders |
oak_render_backend_cap_blit | oak_render_backend_cap_readback |
oak_render_backend_cap_viewer_context;
out_info->name = "opengl";
out_info->status = "available";
return true;
@@ -83,35 +83,35 @@ oak_renderer_is_available(OakRenderBackendHandle handle)
// Initializes an offscreen OpenGL context for non-viewer users.
OAK_RENDER_BACKEND_EXPORT bool oak_renderer_init(OakRenderBackendHandle handle)
{
return Renderer(handle)->Init();
return renderer(handle)->init();
}
// Initializes the backend against a caller-owned viewer OpenGL context.
OAK_RENDER_BACKEND_EXPORT void
oak_renderer_init_with_context(OakRenderBackendHandle handle, void *context)
{
Renderer(handle)->Init(static_cast<QOpenGLContext *>(context));
renderer(handle)->init(static_cast<QOpenGLContext *>(context));
}
// Runs renderer post-initialization once the GL context is available.
OAK_RENDER_BACKEND_EXPORT void
oak_renderer_post_init(OakRenderBackendHandle handle)
{
Renderer(handle)->PostInit();
renderer(handle)->post_init();
}
// Releases post-init OpenGL surface/context state.
OAK_RENDER_BACKEND_EXPORT void
oak_renderer_post_destroy(OakRenderBackendHandle handle)
{
Renderer(handle)->PostDestroy();
renderer(handle)->post_destroy();
}
// Releases renderer-owned GL resources before object destruction.
OAK_RENDER_BACKEND_EXPORT void
oak_renderer_destroy_internal(OakRenderBackendHandle handle)
{
Renderer(handle)->DestroyInternal();
renderer(handle)->destroy_internal();
}
// Clears either the widget framebuffer or a texture destination.
@@ -119,7 +119,7 @@ OAK_RENDER_BACKEND_EXPORT void
oak_renderer_clear_destination(OakRenderBackendHandle handle, void *texture,
double r, double g, double b, double a)
{
Renderer(handle)->ClearDestination(static_cast<olive::Texture *>(texture),
renderer(handle)->clear_destination(static_cast<olive::Texture *>(texture),
r, g, b, a);
}
@@ -129,7 +129,7 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_create_native_texture(
int channel_count, const void *data, int linesize, void *out_variant)
{
*static_cast<QVariant *>(out_variant) =
Renderer(handle)->CreateNativeTexture(
renderer(handle)->create_native_texture(
width, height, depth,
static_cast<olive::PixelFormat::Format>(format), channel_count,
data, linesize);
@@ -140,7 +140,7 @@ OAK_RENDER_BACKEND_EXPORT void
oak_renderer_destroy_native_texture(OakRenderBackendHandle handle,
const void *variant)
{
Renderer(handle)->DestroyNativeTexture(VariantRef(variant));
renderer(handle)->destroy_native_texture(variant_ref(variant));
}
// Compiles an OpenGL shader program and returns its QVariant handle.
@@ -149,7 +149,7 @@ oak_renderer_create_native_shader(OakRenderBackendHandle handle,
const void *shader_code, void *out_variant)
{
*static_cast<QVariant *>(out_variant) =
Renderer(handle)->CreateNativeShader(
renderer(handle)->create_native_shader(
*static_cast<const olive::ShaderCode *>(shader_code));
}
@@ -158,7 +158,7 @@ OAK_RENDER_BACKEND_EXPORT void
oak_renderer_destroy_native_shader(OakRenderBackendHandle handle,
const void *variant)
{
Renderer(handle)->DestroyNativeShader(VariantRef(variant));
renderer(handle)->destroy_native_shader(variant_ref(variant));
}
// Uploads CPU pixel data into an OpenGL texture.
@@ -167,8 +167,8 @@ oak_renderer_upload_to_texture(OakRenderBackendHandle handle,
const void *variant, const void *video_params,
const void *data, int linesize)
{
Renderer(handle)->UploadToTexture(
VariantRef(variant),
renderer(handle)->upload_to_texture(
variant_ref(variant),
*static_cast<const olive::VideoParams *>(video_params), data, linesize);
}
@@ -177,15 +177,15 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_download_from_texture(
OakRenderBackendHandle handle, const void *variant,
const void *video_params, void *data, int linesize)
{
Renderer(handle)->DownloadFromTexture(
VariantRef(variant),
renderer(handle)->download_from_texture(
variant_ref(variant),
*static_cast<const olive::VideoParams *>(video_params), data, linesize);
}
// Flushes/waits for pending OpenGL work as required by the renderer.
OAK_RENDER_BACKEND_EXPORT void oak_renderer_flush(OakRenderBackendHandle handle)
{
Renderer(handle)->Flush();
renderer(handle)->flush();
}
// Reads one pixel from an OpenGL texture.
@@ -195,7 +195,7 @@ oak_renderer_get_pixel_from_texture(OakRenderBackendHandle handle,
void *out_color)
{
*static_cast<olive::Color *>(out_color) =
Renderer(handle)->GetPixelFromTexture(
renderer(handle)->get_pixel_from_texture(
static_cast<olive::Texture *>(texture),
*static_cast<const QPointF *>(point));
}
@@ -207,8 +207,8 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_blit(OakRenderBackendHandle handle,
const void *destination_params,
bool clear_destination)
{
Renderer(handle)->Blit(
VariantRef(shader), *static_cast<olive::AcceleratedJob *>(job),
renderer(handle)->blit(
variant_ref(shader), *static_cast<olive::AcceleratedJob *>(job),
static_cast<olive::Texture *>(destination),
*static_cast<const olive::VideoParams *>(destination_params),
clear_destination);
@@ -218,7 +218,7 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_blit(OakRenderBackendHandle handle,
OAK_RENDER_BACKEND_EXPORT void *
oak_renderer_opengl_context(OakRenderBackendHandle handle)
{
return Renderer(handle)->context();
return renderer(handle)->context();
}
// Binds an output texture for OFX OpenGL rendering.
@@ -226,12 +226,12 @@ OAK_RENDER_BACKEND_EXPORT void
oak_renderer_attach_output_texture(OakRenderBackendHandle handle,
const void *texture_id)
{
Renderer(handle)->AttachTextureAsDestination(VariantRef(texture_id));
renderer(handle)->attach_texture_as_destination(variant_ref(texture_id));
}
// Detaches any OFX OpenGL output texture binding.
OAK_RENDER_BACKEND_EXPORT void
oak_renderer_detach_output_texture(OakRenderBackendHandle handle)
{
Renderer(handle)->DetachTextureAsDestination();
renderer(handle)->detach_texture_as_destination();
}
+4 -4
View File
@@ -1,5 +1,5 @@
#ifndef OPENGLCONTEXTPROVIDER_H
#define OPENGLCONTEXTPROVIDER_H
#ifndef OAK_OPENGLCONTEXTPROVIDER_H
#define OAK_OPENGLCONTEXTPROVIDER_H
class QOpenGLContext;
@@ -9,9 +9,9 @@ namespace olive
class OpenGLContextProvider {
public:
virtual ~OpenGLContextProvider() = default;
virtual QOpenGLContext *OpenGLContext() const = 0;
virtual QOpenGLContext *open_gl_context() const = 0;
};
}
#endif // OPENGLCONTEXTPROVIDER_H
#endif // OAK_OPENGLCONTEXTPROVIDER_H
+179 -179
View File
@@ -36,7 +36,7 @@
namespace olive
{
const int OpenGLRenderer::kTextureCacheMaxSize = 5000;
const int OpenGLRenderer::k_texture_cache_max_size = 5000;
const QVector<GLfloat> blit_vertices = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f,
0.0f, 1.0f, 1.0f, 0.0f,
@@ -73,9 +73,9 @@ private:
QOpenGLFunctions *functions_;
};
#define PRINT_GL_ERRORS ErrorPrinter __e(__FUNCTION__, functions_)
#define OAK_PRINT_GL_ERRORS ErrorPrinter __e(__FUNCTION__, functions_)
#define GL_PREAMBLE //QMutexLocker __l(&global_opengl_mutex);
#define OAK_GL_PREAMBLE //QMutexLocker __l(&global_opengl_mutex);
//QMutex global_opengl_mutex;
@@ -90,11 +90,11 @@ OpenGLRenderer::OpenGLRenderer(QObject *parent)
OpenGLRenderer::~OpenGLRenderer()
{
Destroy();
PostDestroy();
destroy();
post_destroy();
}
void OpenGLRenderer::Init(QOpenGLContext *existing_ctx)
void OpenGLRenderer::init(QOpenGLContext *existing_ctx)
{
if (context_) {
qCritical() << "Can't initialize already initialized OpenGLRenderer";
@@ -104,9 +104,9 @@ void OpenGLRenderer::Init(QOpenGLContext *existing_ctx)
context_ = existing_ctx;
}
bool OpenGLRenderer::Init()
bool OpenGLRenderer::init()
{
GL_PREAMBLE;
OAK_GL_PREAMBLE;
if (context_) {
qCritical() << "Can't initialize already initialized OpenGLRenderer";
@@ -125,7 +125,7 @@ bool OpenGLRenderer::Init()
return true;
}
void OpenGLRenderer::PostDestroy()
void OpenGLRenderer::post_destroy()
{
// Destroy surface if we created it
if (surface_.isValid()) {
@@ -133,9 +133,9 @@ void OpenGLRenderer::PostDestroy()
}
}
void OpenGLRenderer::PostInit()
void OpenGLRenderer::post_init()
{
GL_PREAMBLE;
OAK_GL_PREAMBLE;
if (!context_) {
qWarning() << __FUNCTION__ << "called without an OpenGL context";
@@ -162,12 +162,12 @@ void OpenGLRenderer::PostInit()
}
}
void OpenGLRenderer::DestroyInternal()
void OpenGLRenderer::destroy_internal()
{
// context_ is guarded: if a caller-owned context was already destroyed,
// this is null and there is nothing GL-side left to release.
if (context_) {
GL_PREAMBLE;
OAK_GL_PREAMBLE;
if (functions_ && framebuffer_) {
functions_->glDeleteFramebuffers(1, &framebuffer_);
@@ -186,33 +186,33 @@ void OpenGLRenderer::DestroyInternal()
functions_ = nullptr;
}
void OpenGLRenderer::ClearDestination(Texture *texture, double r, double g,
void OpenGLRenderer::clear_destination(Texture *texture, double r, double g,
double b, double a)
{
GL_PREAMBLE;
OAK_GL_PREAMBLE;
if (!EnsureContextCurrent(__FUNCTION__)) {
if (!ensure_context_current(__FUNCTION__)) {
return;
}
if (texture) {
AttachTextureAsDestination(texture->id());
attach_texture_as_destination(texture->id());
}
ClearDestinationInternal(r, g, b, a);
clear_destination_internal(r, g, b, a);
if (texture) {
DetachTextureAsDestination();
detach_texture_as_destination();
}
}
QVariant OpenGLRenderer::CreateNativeTexture(int width, int height, int depth,
QVariant OpenGLRenderer::create_native_texture(int width, int height, int depth,
PixelFormat format,
int channel_count,
const void *data, int linesize)
{
GL_PREAMBLE;
if (!EnsureContextCurrent(__FUNCTION__)) {
OAK_GL_PREAMBLE;
if (!ensure_context_current(__FUNCTION__)) {
return QVariant();
}
@@ -237,13 +237,13 @@ QVariant OpenGLRenderer::CreateNativeTexture(int width, int height, int depth,
if (is_3d) {
context_->extraFunctions()->glTexImage3D(
target, 0, GetInternalFormat(format, channel_count), width, height,
depth, 0, GetPixelFormat(channel_count), GetPixelType(format),
target, 0, get_internal_format(format, channel_count), width, height,
depth, 0, get_pixel_format(channel_count), get_pixel_type(format),
data);
} else {
functions_->glTexImage2D(
target, 0, GetInternalFormat(format, channel_count), width, height,
0, GetPixelFormat(channel_count), GetPixelType(format), data);
target, 0, get_internal_format(format, channel_count), width, height,
0, get_pixel_format(channel_count), get_pixel_type(format), data);
}
functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@@ -253,9 +253,9 @@ QVariant OpenGLRenderer::CreateNativeTexture(int width, int height, int depth,
return texture;
}
void OpenGLRenderer::AttachTextureAsDestination(const QVariant &texture)
void OpenGLRenderer::attach_texture_as_destination(const QVariant &texture)
{
PRINT_GL_ERRORS;
OAK_PRINT_GL_ERRORS;
if (!framebuffer_) {
functions_->glGenFramebuffers(1, &framebuffer_);
@@ -267,7 +267,7 @@ void OpenGLRenderer::AttachTextureAsDestination(const QVariant &texture)
0);
}
void OpenGLRenderer::DetachTextureAsDestination()
void OpenGLRenderer::detach_texture_as_destination()
{
// QOpenGLWidget renders to a non-zero default FBO.
const GLuint default_fbo = context_ ? context_->defaultFramebufferObject() :
@@ -275,9 +275,9 @@ void OpenGLRenderer::DetachTextureAsDestination()
functions_->glBindFramebuffer(GL_FRAMEBUFFER, default_fbo);
}
void OpenGLRenderer::DestroyNativeTexture(QVariant texture)
void OpenGLRenderer::destroy_native_texture(QVariant texture)
{
if (!EnsureContextCurrent(__FUNCTION__)) {
if (!ensure_context_current(__FUNCTION__)) {
return;
}
@@ -288,18 +288,18 @@ void OpenGLRenderer::DestroyNativeTexture(QVariant texture)
}
}
QVariant OpenGLRenderer::CreateNativeShader(ShaderCode code)
QVariant OpenGLRenderer::create_native_shader(ShaderCode code)
{
GL_PREAMBLE;
OAK_GL_PREAMBLE;
if (!EnsureContextCurrent(__FUNCTION__)) {
if (!ensure_context_current(__FUNCTION__)) {
return QVariant();
}
PRINT_GL_ERRORS;
OAK_PRINT_GL_ERRORS;
GLuint vert = CompileShader(GL_VERTEX_SHADER, code.vert_code());
GLuint frag = CompileShader(GL_FRAGMENT_SHADER, code.frag_code());
GLuint vert = compile_shader(GL_VERTEX_SHADER, code.vert_code());
GLuint frag = compile_shader(GL_FRAGMENT_SHADER, code.frag_code());
GLuint program = 0;
@@ -324,11 +324,11 @@ QVariant OpenGLRenderer::CreateNativeShader(ShaderCode code)
return program;
}
void OpenGLRenderer::DestroyNativeShader(QVariant shader)
void OpenGLRenderer::destroy_native_shader(QVariant shader)
{
GL_PREAMBLE;
OAK_GL_PREAMBLE;
if (!EnsureContextCurrent(__FUNCTION__)) {
if (!ensure_context_current(__FUNCTION__)) {
return;
}
@@ -336,11 +336,11 @@ void OpenGLRenderer::DestroyNativeShader(QVariant shader)
functions_->glDeleteProgram(program);
}
void OpenGLRenderer::UploadToTexture(const QVariant &handle,
void OpenGLRenderer::upload_to_texture(const QVariant &handle,
const VideoParams &p, const void *data,
int linesize)
{
GL_PREAMBLE;
OAK_GL_PREAMBLE;
GLuint t = handle.value<GLuint>();
@@ -358,18 +358,18 @@ void OpenGLRenderer::UploadToTexture(const QVariant &handle,
functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize);
{
PRINT_GL_ERRORS;
OAK_PRINT_GL_ERRORS;
if (!is_3d) {
functions_->glTexSubImage2D(tex_type, 0, 0, 0, p.effective_width(),
p.effective_height(),
GetPixelFormat(p.channel_count()),
GetPixelType(p.format()), data);
get_pixel_format(p.channel_count()),
get_pixel_type(p.format()), data);
} else {
context_->extraFunctions()->glTexSubImage3D(
tex_type, 0, 0, 0, 0, p.effective_width(), p.effective_height(),
p.effective_depth(), GetPixelFormat(p.channel_count()),
GetPixelType(p.format()), data);
p.effective_depth(), get_pixel_format(p.channel_count()),
get_pixel_type(p.format()), data);
}
}
@@ -378,13 +378,13 @@ void OpenGLRenderer::UploadToTexture(const QVariant &handle,
functions_->glBindTexture(tex_type, current_tex);
}
void OpenGLRenderer::DownloadFromTexture(const QVariant &id,
void OpenGLRenderer::download_from_texture(const QVariant &id,
const VideoParams &p, void *data,
int linesize)
{
GL_PREAMBLE;
OAK_GL_PREAMBLE;
if (!EnsureContextCurrent(__FUNCTION__)) {
if (!ensure_context_current(__FUNCTION__)) {
return;
}
@@ -397,12 +397,12 @@ void OpenGLRenderer::DownloadFromTexture(const QVariant &id,
GLint current_tex;
functions_->glGetIntegerv(GL_TEXTURE_BINDING_2D, &current_tex);
AttachTextureAsDestination(id);
attach_texture_as_destination(id);
GLenum status = functions_->glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
qWarning() << "DownloadFromTexture framebuffer incomplete" << status;
DetachTextureAsDestination();
detach_texture_as_destination();
return;
}
@@ -412,30 +412,30 @@ void OpenGLRenderer::DownloadFromTexture(const QVariant &id,
functions_->glFinish();
{
PRINT_GL_ERRORS;
OAK_PRINT_GL_ERRORS;
functions_->glReadPixels(0, 0, p.effective_width(),
p.effective_height(),
GetPixelFormat(p.channel_count()),
GetPixelType(p.format()), data);
get_pixel_format(p.channel_count()),
get_pixel_type(p.format()), data);
}
functions_->glPixelStorei(GL_PACK_ROW_LENGTH, 0);
DetachTextureAsDestination();
detach_texture_as_destination();
functions_->glBindTexture(GL_TEXTURE_2D, current_tex);
}
void OpenGLRenderer::Flush()
void OpenGLRenderer::flush()
{
GL_PREAMBLE;
OAK_GL_PREAMBLE;
if (!EnsureContextCurrent(__FUNCTION__)) {
if (!ensure_context_current(__FUNCTION__)) {
return;
}
#if !defined(OAK_RENDER_BACKEND_PLUGIN)
if (OLIVE_CONFIG("UseGLFinish").toBool()) {
if (OAK_CONFIG("UseGLFinish").toBool()) {
functions_->glFinish();
return;
}
@@ -454,52 +454,52 @@ void OpenGLRenderer::Flush()
// Adapts the generic Renderer output attachment hook to OpenGL's framebuffer
// attachment path used by OFX OpenGL rendering.
void OpenGLRenderer::AttachOutputTexture(olive::Texture *texture)
void OpenGLRenderer::attach_output_texture(olive::Texture *texture)
{
if (!EnsureContextCurrent(__FUNCTION__)) {
if (!ensure_context_current(__FUNCTION__)) {
return;
}
if (texture) {
AttachTextureAsDestination(texture->id());
attach_texture_as_destination(texture->id());
}
}
// Clears the framebuffer attachment installed by AttachOutputTexture().
void OpenGLRenderer::DetachOutputTexture()
void OpenGLRenderer::detach_output_texture()
{
if (!EnsureContextCurrent(__FUNCTION__)) {
if (!ensure_context_current(__FUNCTION__)) {
return;
}
DetachTextureAsDestination();
detach_texture_as_destination();
}
Color OpenGLRenderer::GetPixelFromTexture(Texture *texture, const QPointF &pt)
Color OpenGLRenderer::get_pixel_from_texture(Texture *texture, const QPointF &pt)
{
if (!texture || !EnsureContextCurrent(__FUNCTION__)) {
if (!texture || !ensure_context_current(__FUNCTION__)) {
return Color();
}
AttachTextureAsDestination(texture->id());
attach_texture_as_destination(texture->id());
QByteArray data(VideoParams::GetBytesPerPixel(texture->format(),
QByteArray data(VideoParams::get_bytes_per_pixel(texture->format(),
texture->channel_count()),
Qt::Uninitialized);
functions_->glReadPixels(pt.x(), pt.y(), 1, 1,
GetPixelFormat(texture->channel_count()),
GetPixelType(texture->format()), data.data());
get_pixel_format(texture->channel_count()),
get_pixel_type(texture->format()), data.data());
Color c = Color::fromData(data.data(), texture->format(),
Color c = Color::from_data(data.data(), texture->format(),
texture->channel_count());
if (texture->channel_count() == VideoParams::kRGBChannelCount) {
if (texture->channel_count() == VideoParams::k_rgb_channel_count) {
// No alpha channel, set to 1.0
c.set_alpha(1.0);
}
DetachTextureAsDestination();
detach_texture_as_destination();
return c;
}
@@ -509,12 +509,12 @@ struct TextureToBind {
Texture::Interpolation interpolation;
};
void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
void OpenGLRenderer::blit(QVariant s, AcceleratedJob &a_job,
Texture *destination, VideoParams destination_params,
bool clear_destination)
{
GL_PREAMBLE;
if (!EnsureContextCurrent(__FUNCTION__)) {
OAK_GL_PREAMBLE;
if (!ensure_context_current(__FUNCTION__)) {
return;
}
try {
@@ -534,8 +534,8 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
functions_->glUseProgram(shader);
for (auto it = job.GetValues().constBegin();
it != job.GetValues().constEnd(); it++) {
for (auto it = job.get_values().constBegin();
it != job.get_values().constEnd(); it++) {
// See if the shader has takes this parameter as an input
GLint variable_location = functions_->glGetUniformLocation(
shader, it.key().toUtf8().constData());
@@ -553,52 +553,52 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
}
switch (value.type()) {
case NodeValue::kInt:
case NodeValue::k_int:
// kInt technically specifies a LongLong, but OpenGL doesn't support those. This may lead to
// over/underflows if the number is large enough, but the likelihood of that is quite low.
functions_->glUniform1i(variable_location, value.toInt());
functions_->glUniform1i(variable_location, value.to_int());
break;
case NodeValue::kFloat:
case NodeValue::k_float:
// kFloat technically specifies a double but as above, OpenGL doesn't support those.
functions_->glUniform1f(variable_location, value.toDouble());
functions_->glUniform1f(variable_location, value.to_double());
break;
case NodeValue::kVec2: {
QVector2D v = value.toVec2();
case NodeValue::k_vec2: {
QVector2D v = value.to_vec2();
functions_->glUniform2fv(variable_location, 1,
reinterpret_cast<const GLfloat *>(&v));
break;
}
case NodeValue::kVec3: {
QVector3D v = value.toVec3();
case NodeValue::k_vec3: {
QVector3D v = value.to_vec3();
functions_->glUniform3fv(variable_location, 1,
reinterpret_cast<const GLfloat *>(&v));
break;
}
case NodeValue::kVec4: {
QVector4D v = value.toVec4();
case NodeValue::k_vec4: {
QVector4D v = value.to_vec4();
functions_->glUniform4fv(variable_location, 1,
reinterpret_cast<const GLfloat *>(&v));
break;
}
case NodeValue::kMatrix:
case NodeValue::k_matrix:
functions_->glUniformMatrix4fv(variable_location, 1, false,
value.toMatrix().constData());
value.to_matrix().constData());
break;
case NodeValue::kCombo:
functions_->glUniform1i(variable_location, value.toInt());
case NodeValue::k_combo:
functions_->glUniform1i(variable_location, value.to_int());
break;
case NodeValue::kColor: {
Color color = value.toColor();
case NodeValue::k_color: {
Color color = value.to_color();
functions_->glUniform4f(variable_location, color.red(),
color.green(), color.blue(),
color.alpha());
break;
}
case NodeValue::kBoolean:
functions_->glUniform1i(variable_location, value.toBool());
case NodeValue::k_boolean:
functions_->glUniform1i(variable_location, value.to_bool());
break;
case NodeValue::kTexture: {
TexturePtr texture = value.toTexture();
case NodeValue::k_texture: {
TexturePtr texture = value.to_texture();
// Set value to bound texture
functions_->glUniform1i(variable_location,
@@ -607,7 +607,7 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
texture_index_map.insert(it.key(), textures_to_bind.size());
textures_to_bind.append(
{ texture, job.GetInterpolation(it.key()) });
{ texture, job.get_interpolation(it.key()) });
// Set enable flag if shader wants it
GLuint tex_id = texture ? texture->id().value<GLuint>() : 0;
@@ -621,18 +621,18 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
}
break;
}
case NodeValue::kSamples:
case NodeValue::kText:
case NodeValue::kRational:
case NodeValue::kFont:
case NodeValue::kFile:
case NodeValue::kVideoParams:
case NodeValue::kAudioParams:
case NodeValue::kSubtitleParams:
case NodeValue::kBezier:
case NodeValue::kBinary:
case NodeValue::kNone:
case NodeValue::kDataTypeCount:
case NodeValue::k_samples:
case NodeValue::k_text:
case NodeValue::k_rational:
case NodeValue::k_font:
case NodeValue::k_file:
case NodeValue::k_video_params:
case NodeValue::k_audio_params:
case NodeValue::k_subtitle_params:
case NodeValue::k_bezier:
case NodeValue::k_binary:
case NodeValue::k_none:
case NodeValue::k_data_type_count:
break;
}
}
@@ -652,7 +652,7 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
functions_->glBindTexture(target, tex_id);
if (tex_id) {
PrepareInputTexture(target, t.interpolation);
prepare_input_texture(target, t.interpolation);
if (texture->channel_count() == 1 &&
destination_params.channel_count() != 1) {
@@ -673,7 +673,7 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
if (mvpmat_location > -1) {
functions_->glUniformMatrix4fv(
mvpmat_location, 1, false,
job.Get(QStringLiteral("ove_mvpmat")).toMatrix().constData());
job.get(QStringLiteral("ove_mvpmat")).to_matrix().constData());
}
// Set the viewport to the "physical" resolution of the destination
@@ -681,51 +681,51 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
destination_params.effective_height());
// Bind vertex array object
QOpenGLVertexArrayObject vao_;
vao_.create();
vao_.bind();
QOpenGLVertexArrayObject vao;
vao.create();
vao.bind();
// Set buffers
QOpenGLBuffer vert_vbo_;
vert_vbo_.create();
vert_vbo_.bind();
QOpenGLBuffer vert_vbo;
vert_vbo.create();
vert_vbo.bind();
// If the job has vertex coordinate overrides use them instead of the defaults.
if (!job.GetVertexCoordinates().isEmpty()) {
Q_ASSERT(job.GetVertexCoordinates().size() == 18);
vert_vbo_.allocate(job.GetVertexCoordinates().constData(),
job.GetVertexCoordinates().size() *
if (!job.get_vertex_coordinates().isEmpty()) {
Q_ASSERT(job.get_vertex_coordinates().size() == 18);
vert_vbo.allocate(job.get_vertex_coordinates().constData(),
job.get_vertex_coordinates().size() *
sizeof(float));
} else {
vert_vbo_.allocate(blit_vertices.constData(),
vert_vbo.allocate(blit_vertices.constData(),
blit_vertices.size() * sizeof(GLfloat));
}
vert_vbo_.release();
vert_vbo.release();
QOpenGLBuffer frag_vbo_;
frag_vbo_.create();
frag_vbo_.bind();
frag_vbo_.allocate(blit_texcoords.constData(),
QOpenGLBuffer frag_vbo;
frag_vbo.create();
frag_vbo.bind();
frag_vbo.allocate(blit_texcoords.constData(),
blit_texcoords.size() * sizeof(GLfloat));
frag_vbo_.release();
frag_vbo.release();
GLint vertex_location =
functions_->glGetAttribLocation(shader, "a_position");
if (vertex_location != -1) {
vert_vbo_.bind();
vert_vbo.bind();
functions_->glEnableVertexAttribArray(vertex_location);
functions_->glVertexAttribPointer(vertex_location, 3, GL_FLOAT,
GL_FALSE, 0, nullptr);
vert_vbo_.release();
vert_vbo.release();
}
GLint tex_location =
functions_->glGetAttribLocation(shader, "a_texcoord");
if (tex_location != -1) {
frag_vbo_.bind();
frag_vbo.bind();
functions_->glEnableVertexAttribArray(tex_location);
functions_->glVertexAttribPointer(tex_location, 2, GL_FLOAT,
GL_FALSE, 0, nullptr);
frag_vbo_.release();
frag_vbo.release();
}
// Some shaders optimize through multiple iterations which requires ping-ponging textures
@@ -735,8 +735,8 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
// textures. We can still use the destination as the last iteration, but we'll need textures
// for the iterative process.
int real_iteration_count;
if (job.GetIterationCount() > 1 && !job.GetIterativeInput().isEmpty()) {
real_iteration_count = job.GetIterationCount();
if (job.get_iteration_count() > 1 && !job.get_iterative_input().isEmpty()) {
real_iteration_count = job.get_iteration_count();
} else {
real_iteration_count = 1;
}
@@ -744,11 +744,11 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
TexturePtr output_tex, input_tex;
if (real_iteration_count > 1) {
// Create one texture to bounce off
output_tex = CreateTexture(destination_params);
output_tex = create_texture(destination_params);
if (real_iteration_count > 2) {
// Create a second texture bounce off
input_tex = CreateTexture(destination_params);
input_tex = create_texture(destination_params);
}
}
@@ -765,33 +765,33 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
// This is the last iteration, draw to the destination
if (destination) {
// If we have a destination texture, draw to it
AttachTextureAsDestination(destination->id());
attach_texture_as_destination(destination->id());
} else if (iteration > 0) {
// Otherwise, if we were iterating before, detach texture now
DetachTextureAsDestination();
detach_texture_as_destination();
}
// Clear the destination if the caller requested it
if (clear_destination) {
ClearDestinationInternal();
clear_destination_internal();
}
} else {
// Always draw to output_tex, which gets swapped with input_tex every iteration
AttachTextureAsDestination(output_tex->id());
attach_texture_as_destination(output_tex->id());
}
if (iteration > 0) {
// If this is not the first iteration, replace the iterative texture with the one we
// last drew
const QString &iterative_input = job.GetIterativeInput();
const QString &iterative_input = job.get_iterative_input();
functions_->glActiveTexture(
GL_TEXTURE0 + texture_index_map.value(iterative_input));
functions_->glBindTexture(GL_TEXTURE_2D,
input_tex->id().value<GLuint>());
// At this time, we only support iterating 2D textures
PrepareInputTexture(GL_TEXTURE_2D,
job.GetInterpolation(iterative_input));
prepare_input_texture(GL_TEXTURE_2D,
job.get_interpolation(iterative_input));
}
// Swap so that the next iteration, the texture we draw now will be the input texture next
@@ -799,7 +799,7 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
// Blit this texture through this shader
{
PRINT_GL_ERRORS;
OAK_PRINT_GL_ERRORS;
functions_->glDrawArrays(GL_TRIANGLES, 0,
blit_vertices.size() / 3);
}
@@ -807,7 +807,7 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
if (destination) {
// Reset framebuffer to default if we were drawing to a texture
DetachTextureAsDestination();
detach_texture_as_destination();
}
// Release any textures we bound before
@@ -824,18 +824,18 @@ void OpenGLRenderer::Blit(QVariant s, AcceleratedJob &a_job,
functions_->glUseProgram(0);
// Release vertex array object
frag_vbo_.destroy();
vert_vbo_.destroy();
vao_.release();
vao_.destroy();
frag_vbo.destroy();
vert_vbo.destroy();
vao.release();
vao.destroy();
} catch (std::bad_cast e) {
}
}
GLint OpenGLRenderer::GetInternalFormat(PixelFormat format, int channel_layout)
GLint OpenGLRenderer::get_internal_format(PixelFormat format, int channel_layout)
{
switch (format) {
case PixelFormat::U8:
case PixelFormat::u8:
switch (channel_layout) {
case 1:
return GL_R8;
@@ -847,12 +847,12 @@ GLint OpenGLRenderer::GetInternalFormat(PixelFormat format, int channel_layout)
return GL_RGBA8;
}
break;
case PixelFormat::U10:
case PixelFormat::u10:
if (channel_layout == 4) {
return GL_RGB10_A2;
}
break;
case PixelFormat::U16:
case PixelFormat::u16:
switch (channel_layout) {
case 1:
return GL_R16;
@@ -864,7 +864,7 @@ GLint OpenGLRenderer::GetInternalFormat(PixelFormat format, int channel_layout)
return GL_RGBA16;
}
break;
case PixelFormat::F16:
case PixelFormat::f16:
switch (channel_layout) {
case 1:
return GL_R16F;
@@ -876,7 +876,7 @@ GLint OpenGLRenderer::GetInternalFormat(PixelFormat format, int channel_layout)
return GL_RGBA16F;
}
break;
case PixelFormat::F32:
case PixelFormat::f32:
switch (channel_layout) {
case 1:
return GL_R32F;
@@ -888,37 +888,37 @@ GLint OpenGLRenderer::GetInternalFormat(PixelFormat format, int channel_layout)
return GL_RGBA32F;
}
break;
case PixelFormat::INVALID:
case PixelFormat::COUNT:
case PixelFormat::invalid:
case PixelFormat::count:
break;
}
return GL_INVALID_VALUE;
}
GLenum OpenGLRenderer::GetPixelType(PixelFormat format)
GLenum OpenGLRenderer::get_pixel_type(PixelFormat format)
{
switch (format) {
case PixelFormat::U8:
case PixelFormat::u8:
return GL_UNSIGNED_BYTE;
case PixelFormat::U10:
case PixelFormat::u10:
return GL_UNSIGNED_INT_2_10_10_10_REV;
case PixelFormat::U16:
case PixelFormat::u16:
return GL_UNSIGNED_SHORT;
case PixelFormat::F16:
case PixelFormat::f16:
return GL_HALF_FLOAT;
case PixelFormat::F32:
case PixelFormat::f32:
return GL_FLOAT;
case PixelFormat::INVALID:
case PixelFormat::COUNT:
case PixelFormat::invalid:
case PixelFormat::count:
break;
}
return GL_INVALID_VALUE;
}
GLenum OpenGLRenderer::GetPixelFormat(int channel_count)
GLenum OpenGLRenderer::get_pixel_format(int channel_count)
{
switch (channel_count) {
case 1:
@@ -932,19 +932,19 @@ GLenum OpenGLRenderer::GetPixelFormat(int channel_count)
}
}
void OpenGLRenderer::PrepareInputTexture(GLenum target,
void OpenGLRenderer::prepare_input_texture(GLenum target,
Texture::Interpolation interp)
{
switch (interp) {
case Texture::kNearest:
case Texture::k_nearest:
functions_->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
functions_->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
break;
case Texture::kLinear:
case Texture::k_linear:
functions_->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
functions_->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
break;
case Texture::kMipmappedLinear:
case Texture::k_mipmapped_linear:
functions_->glGenerateMipmap(target);
functions_->glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);
@@ -961,7 +961,7 @@ void OpenGLRenderer::PrepareInputTexture(GLenum target,
}
}
void OpenGLRenderer::ClearDestinationInternal(double r, double g, double b,
void OpenGLRenderer::clear_destination_internal(double r, double g, double b,
double a)
{
if (!functions_) {
@@ -971,7 +971,7 @@ void OpenGLRenderer::ClearDestinationInternal(double r, double g, double b,
functions_->glClear(GL_COLOR_BUFFER_BIT);
}
GLuint OpenGLRenderer::CompileShader(GLenum type, const QString &code)
GLuint OpenGLRenderer::compile_shader(GLenum type, const QString &code)
{
const bool is_gles = context_ && context_->isOpenGLES();
const int major = context_ ? context_->format().majorVersion() : 0;
@@ -993,10 +993,10 @@ GLuint OpenGLRenderer::CompileShader(GLenum type, const QString &code)
if (base_code.isEmpty()) {
// Use default code
if (type == GL_FRAGMENT_SHADER) {
base_code = FileFunctions::ReadFileAsString(
base_code = FileFunctions::read_file_as_string(
QStringLiteral(":/shaders/default.frag"));
} else if (type == GL_VERTEX_SHADER) {
base_code = FileFunctions::ReadFileAsString(
base_code = FileFunctions::read_file_as_string(
QStringLiteral(":/shaders/default.vert"));
}
}
@@ -1064,7 +1064,7 @@ GLuint OpenGLRenderer::CompileShader(GLenum type, const QString &code)
return shader;
}
bool OpenGLRenderer::EnsureContextCurrent(const char *caller)
bool OpenGLRenderer::ensure_context_current(const char *caller)
{
if (!context_) {
qWarning() << caller << "called without an OpenGL context";
+32 -32
View File
@@ -19,8 +19,8 @@
***/
#ifndef OPENGLCONTEXT_H
#define OPENGLCONTEXT_H
#ifndef OAK_OPENGLCONTEXT_H
#define OAK_OPENGLCONTEXT_H
#include <QOffscreenSurface>
#include <QOpenGLBuffer>
@@ -44,33 +44,33 @@ public:
virtual ~OpenGLRenderer() override;
void Init(QOpenGLContext *existing_ctx);
void init(QOpenGLContext *existing_ctx);
virtual bool Init() override;
virtual bool init() override;
virtual void PostDestroy() override;
virtual void post_destroy() override;
virtual void PostInit() override;
virtual void post_init() override;
virtual void ClearDestination(olive::Texture *texture = nullptr,
virtual void clear_destination(olive::Texture *texture = nullptr,
double r = 0.0, double g = 0.0,
double b = 0.0, double a = 0.0) override;
virtual QVariant CreateNativeShader(olive::ShaderCode code) override;
virtual QVariant create_native_shader(olive::ShaderCode code) override;
virtual void DestroyNativeShader(QVariant shader) override;
virtual void destroy_native_shader(QVariant shader) override;
virtual void UploadToTexture(const QVariant &handle,
virtual void upload_to_texture(const QVariant &handle,
const VideoParams &params, const void *data,
int linesize) override;
virtual void DownloadFromTexture(const QVariant &handle,
virtual void download_from_texture(const QVariant &handle,
const VideoParams &params, void *data,
int linesize) override;
virtual void Flush() override;
virtual void flush() override;
virtual Color GetPixelFromTexture(olive::Texture *texture,
virtual Color get_pixel_from_texture(olive::Texture *texture,
const QPointF &pt) override;
QOpenGLContext *context() const
@@ -78,54 +78,54 @@ public:
return context_.data();
}
virtual QOpenGLContext *OpenGLContext() const override
virtual QOpenGLContext *open_gl_context() const override
{
return context();
}
virtual bool IsOpenGL() const override
virtual bool is_open_gl() const override
{
return true;
}
virtual void AttachOutputTexture(olive::Texture *texture) override;
virtual void attach_output_texture(olive::Texture *texture) override;
virtual void DetachOutputTexture() override;
virtual void detach_output_texture() override;
bool EnsureContextCurrent(const char *caller);
bool ensure_context_current(const char *caller);
protected:
virtual void Blit(QVariant shader, olive::AcceleratedJob &job,
virtual void blit(QVariant shader, olive::AcceleratedJob &job,
olive::Texture *destination,
olive::VideoParams destination_params,
bool clear_destination) override;
virtual QVariant CreateNativeTexture(int width, int height, int depth,
virtual QVariant create_native_texture(int width, int height, int depth,
PixelFormat format, int channel_count,
const void *data = nullptr,
int linesize = 0) override;
virtual void DestroyNativeTexture(QVariant texture) override;
virtual void destroy_native_texture(QVariant texture) override;
virtual void DestroyInternal() override;
virtual void destroy_internal() override;
void AttachTextureAsDestination(const QVariant &texture);
void attach_texture_as_destination(const QVariant &texture);
void DetachTextureAsDestination();
void detach_texture_as_destination();
private:
static GLint GetInternalFormat(PixelFormat format, int channel_layout);
static GLint get_internal_format(PixelFormat format, int channel_layout);
static GLenum GetPixelType(PixelFormat format);
static GLenum get_pixel_type(PixelFormat format);
static GLenum GetPixelFormat(int channel_count);
static GLenum get_pixel_format(int channel_count);
void PrepareInputTexture(GLenum target, Texture::Interpolation interp);
void prepare_input_texture(GLenum target, Texture::Interpolation interp);
void ClearDestinationInternal(double r = 0.0, double g = 0.0,
void clear_destination_internal(double r = 0.0, double g = 0.0,
double b = 0.0, double a = 0.0);
GLuint CompileShader(GLenum type, const QString &code);
GLuint compile_shader(GLenum type, const QString &code);
// Guarded pointer: viewer contexts are owned by the widget that created
// them and may be destroyed before this renderer (e.g. when a QOpenGLWidget
@@ -156,9 +156,9 @@ private:
QMap<GLuint, TextureCacheKey> texture_params_;
static const int kTextureCacheMaxSize;
static const int k_texture_cache_max_size;
};
}
#endif // OPENGLCONTEXT_H
#endif // OAK_OPENGLCONTEXT_H
+43 -43
View File
@@ -29,7 +29,7 @@
namespace olive
{
void PlaybackCache::Invalidate(const TimeRange &r)
void PlaybackCache::invalidate(const TimeRange &r)
{
if (r.in() == r.out()) {
qWarning() << "Tried to invalidate zero-length range";
@@ -44,10 +44,10 @@ void PlaybackCache::Invalidate(const TimeRange &r)
InvalidateEvent(r);
emit Invalidated(r);
emit invalidated(r);
if (saving_enabled_) {
SaveState();
save_state();
}
}
@@ -56,20 +56,20 @@ Node *PlaybackCache::parent() const
return dynamic_cast<Node *>(QObject::parent());
}
QDir PlaybackCache::GetThisCacheDirectory() const
QDir PlaybackCache::get_this_cache_directory() const
{
return GetThisCacheDirectory(GetCacheDirectory(), GetUuid());
return get_this_cache_directory(get_cache_directory(), get_uuid());
}
QDir PlaybackCache::GetThisCacheDirectory(const QString &cache_path,
QDir PlaybackCache::get_this_cache_directory(const QString &cache_path,
const QUuid &cache_id)
{
return QDir(cache_path).filePath(cache_id.toString());
}
void PlaybackCache::LoadState()
void PlaybackCache::load_state()
{
QDir cache_dir = GetThisCacheDirectory();
QDir cache_dir = get_this_cache_directory();
QFile f(cache_dir.filePath(QStringLiteral("state")));
if (!f.exists()) {
@@ -102,8 +102,8 @@ void PlaybackCache::LoadState()
s >> out_num;
s >> out_den;
validated_.insert(TimeRange(rational(in_num, in_den),
rational(out_num, out_den)));
validated_.insert(TimeRange(Rational(in_num, in_den),
Rational(out_num, out_den)));
}
s >> pass_count;
@@ -117,8 +117,8 @@ void PlaybackCache::LoadState()
s >> out_den;
s >> id;
Passthrough p = TimeRange(rational(in_num, in_den),
rational(out_num, out_den));
Passthrough p = TimeRange(Rational(in_num, in_den),
Rational(out_num, out_den));
p.cache = id;
passthroughs_.push_back(p);
}
@@ -133,20 +133,20 @@ void PlaybackCache::LoadState()
}
}
void PlaybackCache::SaveState()
void PlaybackCache::save_state()
{
if (!DiskManager::instance()) {
return;
}
QDir cache_dir = GetThisCacheDirectory();
QDir cache_dir = get_this_cache_directory();
QFile f(cache_dir.filePath(QStringLiteral("state")));
if (validated_.isEmpty() && passthroughs_.empty()) {
if (f.exists()) {
f.remove();
}
} else {
if (FileFunctions::DirectoryIsValid(cache_dir)) {
if (FileFunctions::directory_is_valid(cache_dir)) {
if (f.open(QFile::WriteOnly)) {
QDataStream s(&f);
@@ -186,19 +186,19 @@ void PlaybackCache::SaveState()
}
}
void PlaybackCache::Draw(QPainter *p, const rational &start, double scale,
void PlaybackCache::draw(QPainter *p, const Rational &start, double scale,
const QRect &rect) const
{
p->fillRect(rect, Qt::red);
foreach (const TimeRange &range, GetValidatedRanges()) {
int range_left = rect.left() + (range.in() - start).toDouble() * scale;
foreach (const TimeRange &range, get_validated_ranges()) {
int range_left = rect.left() + (range.in() - start).to_double() * scale;
if (range_left >= rect.right()) {
continue;
}
int range_right =
rect.left() + (range.out() - start).toDouble() * scale;
rect.left() + (range.out() - start).to_double() * scale;
if (range_right < rect.left()) {
continue;
}
@@ -211,45 +211,45 @@ void PlaybackCache::Draw(QPainter *p, const rational &start, double scale,
}
}
void PlaybackCache::SetPassthrough(PlaybackCache *cache)
void PlaybackCache::set_passthrough(PlaybackCache *cache)
{
for (const TimeRange &r : cache->GetValidatedRanges()) {
for (const TimeRange &r : cache->get_validated_ranges()) {
Passthrough p = r;
p.cache = cache->GetUuid();
p.cache = cache->get_uuid();
passthroughs_.push_back(p);
}
passthroughs_.insert(passthroughs_.end(), cache->GetPassthroughs().begin(),
cache->GetPassthroughs().end());
passthroughs_.insert(passthroughs_.end(), cache->get_passthroughs().begin(),
cache->get_passthroughs().end());
if (saving_enabled_) {
SaveState();
save_state();
}
}
void PlaybackCache::InvalidateAll()
void PlaybackCache::invalidate_all()
{
Invalidate(TimeRange(0, RATIONAL_MAX));
invalidate(TimeRange(0, RATIONAL_MAX));
}
void PlaybackCache::Request(ViewerOutput *context, const TimeRange &r)
void PlaybackCache::request(ViewerOutput *context, const TimeRange &r)
{
request_context_ = context;
requested_.insert(r);
emit Requested(request_context_, r);
emit requested(request_context_, r);
}
void PlaybackCache::Validate(const TimeRange &r, bool signal)
void PlaybackCache::validate(const TimeRange &r, bool signal)
{
validated_.insert(r);
if (signal) {
emit Validated(r);
emit validated(r);
}
if (saving_enabled_) {
SaveState();
save_state();
}
}
@@ -257,9 +257,9 @@ void PlaybackCache::InvalidateEvent(const TimeRange &)
{
}
Project *PlaybackCache::GetProject() const
Project *PlaybackCache::get_project() const
{
return Project::GetProjectFromObject(this);
return Project::get_project_from_object(this);
}
PlaybackCache::PlaybackCache(QObject *parent)
@@ -270,21 +270,21 @@ PlaybackCache::PlaybackCache(QObject *parent)
uuid_ = QUuid::createUuid();
}
void PlaybackCache::SetUuid(const QUuid &u)
void PlaybackCache::set_uuid(const QUuid &u)
{
uuid_ = u;
LoadState();
load_state();
}
TimeRangeList PlaybackCache::GetInvalidatedRanges(TimeRange intersecting) const
TimeRangeList PlaybackCache::get_invalidated_ranges(TimeRange intersecting) const
{
TimeRangeList invalidated;
// Prevent TimeRange from being below 0, some other behavior in Olive relies on this behavior
// and it seemed reasonable to have safety code in here
intersecting.set_out(qMax(rational(0), intersecting.out()));
intersecting.set_in(qMax(rational(0), intersecting.in()));
intersecting.set_out(qMax(Rational(0), intersecting.out()));
intersecting.set_in(qMax(Rational(0), intersecting.in()));
invalidated.insert(intersecting);
@@ -299,19 +299,19 @@ TimeRangeList PlaybackCache::GetInvalidatedRanges(TimeRange intersecting) const
return invalidated;
}
bool PlaybackCache::HasInvalidatedRanges(const TimeRange &intersecting) const
bool PlaybackCache::has_invalidated_ranges(const TimeRange &intersecting) const
{
return !validated_.contains(intersecting);
}
QString PlaybackCache::GetCacheDirectory() const
QString PlaybackCache::get_cache_directory() const
{
Project *project = GetProject();
Project *project = get_project();
if (project) {
return project->cache_path();
} else {
return DiskManager::instance()->GetDefaultCachePath();
return DiskManager::instance()->get_default_cache_path();
}
}
+36 -36
View File
@@ -19,8 +19,8 @@
***/
#ifndef PLAYBACKCACHE_H
#define PLAYBACKCACHE_H
#ifndef OAK_PLAYBACKCACHE_H
#define OAK_PLAYBACKCACHE_H
#include <olive/core/core.h>
#include <QDir>
@@ -45,64 +45,64 @@ class PlaybackCache : public QObject {
public:
PlaybackCache(QObject *parent = nullptr);
const QUuid &GetUuid() const
const QUuid &get_uuid() const
{
return uuid_;
}
void SetUuid(const QUuid &u);
void set_uuid(const QUuid &u);
TimeRangeList GetInvalidatedRanges(TimeRange intersecting) const;
TimeRangeList GetInvalidatedRanges(const rational &length) const
TimeRangeList get_invalidated_ranges(TimeRange intersecting) const;
TimeRangeList get_invalidated_ranges(const Rational &length) const
{
return GetInvalidatedRanges(TimeRange(0, length));
return get_invalidated_ranges(TimeRange(0, length));
}
bool HasInvalidatedRanges(const TimeRange &intersecting) const;
bool HasInvalidatedRanges(const rational &length) const
bool has_invalidated_ranges(const TimeRange &intersecting) const;
bool has_invalidated_ranges(const Rational &length) const
{
return HasInvalidatedRanges(TimeRange(0, length));
return has_invalidated_ranges(TimeRange(0, length));
}
QString GetCacheDirectory() const;
QString get_cache_directory() const;
void Invalidate(const TimeRange &r);
void invalidate(const TimeRange &r);
bool HasValidatedRanges() const
bool has_validated_ranges() const
{
return !validated_.isEmpty();
}
const TimeRangeList &GetValidatedRanges() const
const TimeRangeList &get_validated_ranges() const
{
return validated_;
}
Node *parent() const;
QDir GetThisCacheDirectory() const;
static QDir GetThisCacheDirectory(const QString &cache_path,
QDir get_this_cache_directory() const;
static QDir get_this_cache_directory(const QString &cache_path,
const QUuid &cache_id);
void LoadState();
void SaveState();
void load_state();
void save_state();
void Draw(QPainter *painter, const rational &start, double scale,
void draw(QPainter *painter, const Rational &start, double scale,
const QRect &rect) const;
static int GetCacheIndicatorHeight()
static int get_cache_indicator_height()
{
return QFontMetrics(QFont()).height() / 4;
}
bool IsSavingEnabled() const
bool is_saving_enabled() const
{
return saving_enabled_;
}
void SetSavingEnabled(bool e)
void set_saving_enabled(bool e)
{
saving_enabled_ = e;
}
virtual void SetPassthrough(PlaybackCache *cache);
virtual void set_passthrough(PlaybackCache *cache);
QMutex *mutex()
{
@@ -119,39 +119,39 @@ public:
QUuid cache;
};
const std::vector<Passthrough> &GetPassthroughs() const
const std::vector<Passthrough> &get_passthroughs() const
{
return passthroughs_;
}
void ClearRequestRange(const TimeRange &r)
void clear_request_range(const TimeRange &r)
{
requested_.remove(r);
}
void ResignalRequests()
void resignal_requests()
{
for (const TimeRange &r : requested_) {
emit Requested(request_context_, r);
emit requested(request_context_, r);
}
}
public slots:
void InvalidateAll();
void invalidate_all();
void Request(ViewerOutput *context, const TimeRange &r);
void request(ViewerOutput *context, const TimeRange &r);
signals:
void Invalidated(const TimeRange &r);
void invalidated(const TimeRange &r);
void Validated(const TimeRange &r);
void validated(const TimeRange &r);
void Requested(ViewerOutput *context, const TimeRange &r);
void requested(ViewerOutput *context, const TimeRange &r);
void CancelAll();
void cancel_all();
protected:
void Validate(const TimeRange &r, bool signal = true);
void validate(const TimeRange &r, bool signal = true);
virtual void InvalidateEvent(const TimeRange &range);
@@ -163,7 +163,7 @@ protected:
{
}
Project *GetProject() const;
Project *get_project() const;
private:
TimeRangeList validated_;
@@ -184,4 +184,4 @@ private:
}
#endif // PLAYBACKCACHE_H
#endif // OAK_PLAYBACKCACHE_H
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -21,8 +21,8 @@
// Created by mikesolar on 25-10-19.
//
#ifndef PLUGINRENDERER_H
#define PLUGINRENDERER_H
#ifndef OAK_PLUGINRENDERER_H
#define OAK_PLUGINRENDERER_H
#include <QObject>
@@ -37,7 +37,7 @@ namespace detail
{
// 作用:将字节行跨度转换为像素跨度,便于纹理读写。
// Purpose: Convert byte stride to pixel stride for texture I/O.
int BytesToPixels(int byte_linesize, const olive::VideoParams &params);
int bytes_to_pixels(int byte_linesize, const olive::VideoParams &params);
}
// 作用:OFX 插件渲染器,负责 CPU/GL 路径下的插件调用和纹理桥接。
// Purpose: OFX plugin renderer that drives CPU/GL render paths and texture bridging.
@@ -65,13 +65,13 @@ public:
// 作用:将目标纹理绑定为插件输出。
// Purpose: Attach destination texture as OFX output.
void AttachOutputTexture(olive::TexturePtr texture);
void attach_output_texture(olive::TexturePtr texture);
// 作用:解除目标纹理绑定。
// Purpose: Detach destination texture binding.
void DetachOutputTexture();
void detach_output_texture();
// 作用:执行插件渲染流程(参数配置、输入/输出、调用渲染动作)。
// Purpose: Execute plugin render flow (params, inputs/outputs, render actions).
void RenderPlugin(TexturePtr src, olive::plugin::PluginJob &job,
void render_plugin(TexturePtr src, olive::plugin::PluginJob &job,
olive::TexturePtr destination,
olive::VideoParams destination_params,
bool clear_destination, bool interactive);
@@ -82,4 +82,4 @@ private:
}
}
#endif //PLUGINRENDERER_H
#endif //OAK_PLUGINRENDERER_H
+4 -4
View File
@@ -42,16 +42,16 @@ bool PreviewAudioDevice::isSequential() const
return true;
}
void PreviewAudioDevice::SetParams(const core::AudioParams &params)
void PreviewAudioDevice::set_params(const core::AudioParams &params)
{
set_bytes_per_frame(params.samples_to_bytes(1));
}
qint64 PreviewAudioDevice::readData(char *data, qint64 maxSize)
qint64 PreviewAudioDevice::readData(char *data, qint64 max_size)
{
QMutexLocker locker(&lock_);
qint64 copy_length = qMin(maxSize, qint64(buffer_.size()));
qint64 copy_length = qMin(max_size, qint64(buffer_.size()));
if (copy_length) {
qint64 new_bytes_read = bytes_read_ + copy_length;
@@ -59,7 +59,7 @@ qint64 PreviewAudioDevice::readData(char *data, qint64 maxSize)
if (notify_interval_ > 0) {
if ((bytes_read_ / notify_interval_) !=
(new_bytes_read / notify_interval_)) {
emit Notify();
emit notify();
}
}
+7 -7
View File
@@ -19,8 +19,8 @@
***/
#ifndef PREVIEWAUDIODEVICE_H
#define PREVIEWAUDIODEVICE_H
#ifndef OAK_PREVIEWAUDIODEVICE_H
#define OAK_PREVIEWAUDIODEVICE_H
#include <olive/core/render/audioparams.h>
@@ -36,18 +36,18 @@ public:
virtual ~PreviewAudioDevice() override;
void StartQueuing();
void start_queuing();
virtual bool isSequential() const override;
virtual qint64 readData(char *data, qint64 maxSize) override;
virtual qint64 readData(char *data, qint64 max_size) override;
virtual qint64 writeData(const char *data, qint64 length) override;
// Derives the frame size from the audio format (bytes per sample per
// channel * channel count). Until params are set, bytes_per_frame()
// reports 0, i.e. "unknown".
void SetParams(const core::AudioParams &params);
void set_params(const core::AudioParams &params);
int bytes_per_frame() const
{
@@ -67,7 +67,7 @@ public:
void clear();
signals:
void Notify();
void notify();
private:
QMutex lock_;
@@ -83,4 +83,4 @@ private:
}
#endif // PREVIEWAUDIODEVICE_H
#endif // OAK_PREVIEWAUDIODEVICE_H
+215 -215
View File
@@ -47,66 +47,66 @@ PreviewAutoCacher::PreviewAutoCacher(QObject *parent)
, ignore_cache_requests_(false)
{
copier_ = new ProjectCopier(this);
connect(copier_, &ProjectCopier::AddedNode, this,
&PreviewAutoCacher::ConnectToNodeCache);
connect(copier_, &ProjectCopier::RemovedNode, this,
&PreviewAutoCacher::DisconnectFromNodeCache);
connect(copier_, &ProjectCopier::added_node, this,
&PreviewAutoCacher::connect_to_node_cache);
connect(copier_, &ProjectCopier::removed_node, this,
&PreviewAutoCacher::disconnect_from_node_cache);
// Set defaults
SetPlayhead(0);
set_playhead(0);
// Wait a certain amount of time before requeuing when we receive an invalidate signal
delayed_requeue_timer_.setInterval(OLIVE_CONFIG("AutoCacheDelay").toInt());
delayed_requeue_timer_.setInterval(OAK_CONFIG("AutoCacheDelay").toInt());
delayed_requeue_timer_.setSingleShot(true);
connect(&delayed_requeue_timer_, &QTimer::timeout, this,
&PreviewAutoCacher::TryRender);
&PreviewAutoCacher::try_render);
// Catch when a conform is ready
connect(ConformManager::instance(), &ConformManager::ConformReady, this,
&PreviewAutoCacher::ConformFinished);
connect(ConformManager::instance(), &ConformManager::conform_ready, this,
&PreviewAutoCacher::conform_finished);
}
PreviewAutoCacher::~PreviewAutoCacher()
{
// Ensure everything is cleaned up appropriately
SetProject(nullptr);
set_project(nullptr);
}
RenderTicketPtr PreviewAutoCacher::GetSingleFrame(ViewerOutput *viewer,
const rational &t, bool dry)
RenderTicketPtr PreviewAutoCacher::get_single_frame(ViewerOutput *viewer,
const Rational &t, bool dry)
{
return GetSingleFrame(viewer->GetConnectedTextureOutput(), viewer, t, dry);
return get_single_frame(viewer->get_connected_texture_output(), viewer, t, dry);
}
RenderTicketPtr PreviewAutoCacher::GetSingleFrame(Node *n, ViewerOutput *viewer,
const rational &t, bool dry)
RenderTicketPtr PreviewAutoCacher::get_single_frame(Node *n, ViewerOutput *viewer,
const Rational &t, bool dry)
{
// If we have a single frame render queued (but not yet sent to the RenderManager), cancel it now
CancelQueuedSingleFrameRender();
cancel_queued_single_frame_render();
// Create a new single frame render ticket
auto sfr = std::make_shared<RenderTicket>();
sfr->Start();
sfr->start();
sfr->setProperty("time", QVariant::fromValue(t));
sfr->setProperty("dry", dry);
sfr->setProperty("node", QtUtils::PtrToValue(n));
sfr->setProperty("viewer", QtUtils::PtrToValue(viewer));
sfr->setProperty("node", QtUtils::ptr_to_value(n));
sfr->setProperty("viewer", QtUtils::ptr_to_value(viewer));
// Queue it and try to render
single_frame_render_ = sfr;
TryRender();
try_render();
return sfr;
}
RenderTicketPtr PreviewAutoCacher::GetRangeOfAudio(ViewerOutput *viewer,
RenderTicketPtr PreviewAutoCacher::get_range_of_audio(ViewerOutput *viewer,
TimeRange range)
{
Node *copy = copier_->GetCopy(viewer->GetConnectedSampleOutput());
return RenderAudio(copy, viewer, range, nullptr);
Node *copy = copier_->get_copy(viewer->get_connected_sample_output());
return render_audio(copy, viewer, range, nullptr);
}
void PreviewAutoCacher::ClearSingleFrameRenders()
void PreviewAutoCacher::clear_single_frame_renders()
{
// Snapshot the watchers as guarded pointers before doing anything that
// might synchronously delete them (emitting Finished runs VideoRendered,
@@ -126,18 +126,18 @@ void PreviewAutoCacher::ClearSingleFrameRenders()
// Keep already-running workers alive: cancelling an in-flight render
// forces the worker process to be torn down, which defeats the process
// pool. Frames that finish late are simply ignored by the viewer.
if (w->IsRunning()) {
if (w->is_running()) {
continue;
}
RenderTicketPtr ticket = w->GetTicket();
w->Cancel();
RenderManager::instance()->RemoveTicket(ticket);
emit ticket->Finished();
RenderTicketPtr ticket = w->get_ticket();
w->cancel();
RenderManager::instance()->remove_ticket(ticket);
emit ticket->finished();
}
}
void PreviewAutoCacher::ClearSingleFrameRendersThatArentRunning()
void PreviewAutoCacher::clear_single_frame_renders_that_arent_running()
{
QList<QPointer<RenderTicketWatcher>> watchers;
for (auto it = video_immediate_passthroughs_.cbegin();
@@ -146,38 +146,38 @@ void PreviewAutoCacher::ClearSingleFrameRendersThatArentRunning()
}
foreach (const QPointer<RenderTicketWatcher> &w, watchers) {
if (!w || w->IsRunning()) {
if (!w || w->is_running()) {
continue;
}
RenderTicketPtr ticket = w->GetTicket();
w->Cancel();
RenderManager::instance()->RemoveTicket(ticket);
emit ticket->Finished();
RenderTicketPtr ticket = w->get_ticket();
w->cancel();
RenderManager::instance()->remove_ticket(ticket);
emit ticket->finished();
}
}
void PreviewAutoCacher::VideoInvalidatedFromCache(ViewerOutput *context,
void PreviewAutoCacher::video_invalidated_from_cache(ViewerOutput *context,
const TimeRange &range)
{
PlaybackCache *cache = static_cast<PlaybackCache *>(sender());
cache->ClearRequestRange(range);
cache->clear_request_range(range);
VideoInvalidatedFromNode(context, cache, range);
video_invalidated_from_node(context, cache, range);
}
void PreviewAutoCacher::AudioInvalidatedFromCache(ViewerOutput *context,
void PreviewAutoCacher::audio_invalidated_from_cache(ViewerOutput *context,
const TimeRange &range)
{
PlaybackCache *cache = static_cast<PlaybackCache *>(sender());
cache->ClearRequestRange(range);
cache->clear_request_range(range);
AudioInvalidatedFromNode(context, cache, range);
audio_invalidated_from_node(context, cache, range);
}
void PreviewAutoCacher::CancelForCache()
void PreviewAutoCacher::cancel_for_cache()
{
PlaybackCache *cache = static_cast<PlaybackCache *>(sender());
@@ -204,7 +204,7 @@ void PreviewAutoCacher::CancelForCache()
}
}
void PreviewAutoCacher::AudioRendered()
void PreviewAutoCacher::audio_rendered()
{
// Receive watcher
RenderTicketWatcher *watcher = static_cast<RenderTicketWatcher *>(sender());
@@ -214,11 +214,11 @@ void PreviewAutoCacher::AudioRendered()
if (running_audio_tasks_.removeOne(watcher)) {
// Assume that a "result" is a fully completed image and a non-result is a cancelled ticket
TimeRange range = watcher->property("time").value<TimeRange>();
Node *node = copier_->GetOriginal(
QtUtils::ValueToPtr<Node>(watcher->property("node")));
Node *node = copier_->get_original(
QtUtils::value_to_ptr<Node>(watcher->property("node")));
if (watcher->HasResult() && node) {
if (PlaybackCache *cache = QtUtils::ValueToPtr<PlaybackCache>(
if (watcher->has_result() && node) {
if (PlaybackCache *cache = QtUtils::value_to_ptr<PlaybackCache>(
watcher->property("cache"))) {
AudioCacheData &d = audio_cache_data_[cache];
@@ -229,33 +229,33 @@ void PreviewAutoCacher::AudioRendered()
d.job_tracker.getCurrentSubRanges(range, watcher_job_time);
AudioVisualWaveform waveform =
watcher->GetTicket()
watcher->get_ticket()
->property("waveform")
.value<AudioVisualWaveform>();
SampleBuffer buf = watcher->Get().value<SampleBuffer>();
SampleBuffer buf = watcher->get().value<SampleBuffer>();
bool incomplete =
watcher->GetTicket()->property("incomplete").toBool();
watcher->get_ticket()->property("incomplete").toBool();
if (AudioPlaybackCache *pcm =
dynamic_cast<AudioPlaybackCache *>(cache)) {
// WritePCM is tolerant to its buffer being null, it will just write silence instead
pcm->SetParameters(buf.audio_params());
pcm->WritePCM(range, valid_ranges,
watcher->Get().value<SampleBuffer>());
pcm->set_parameters(buf.audio_params());
pcm->write_pcm(range, valid_ranges,
watcher->get().value<SampleBuffer>());
} else if (AudioWaveformCache *wave =
dynamic_cast<AudioWaveformCache *>(cache)) {
wave->SetParameters(buf.audio_params());
wave->set_parameters(buf.audio_params());
if (!incomplete) {
wave->WriteWaveform(range, valid_ranges, &waveform);
wave->write_waveform(range, valid_ranges, &waveform);
}
}
if (incomplete) {
if (last_conform_task_ > watcher_job_time) {
// Requeue now
cache->Invalidate(range);
cache->invalidate(range);
} else {
// Wait for conform
d.needs_conform.insert(range);
@@ -265,21 +265,21 @@ void PreviewAutoCacher::AudioRendered()
}
// Continue rendering
TryRender();
try_render();
}
delete watcher;
}
void PreviewAutoCacher::VideoRendered()
void PreviewAutoCacher::video_rendered()
{
RenderTicketWatcher *watcher = static_cast<RenderTicketWatcher *>(sender());
const QStringList bad_cache_names =
watcher->GetTicket()->property("badcache").toStringList();
watcher->get_ticket()->property("badcache").toStringList();
if (!bad_cache_names.empty()) {
for (const QString &fn : bad_cache_names) {
DiskManager::instance()->DeleteSpecificFile(fn);
DiskManager::instance()->delete_specific_file(fn);
}
}
@@ -288,12 +288,12 @@ void PreviewAutoCacher::VideoRendered()
QVector<RenderTicketPtr> tickets =
video_immediate_passthroughs_.take(watcher);
foreach (RenderTicketPtr t, tickets) {
if (watcher->HasResult()) {
if (watcher->has_result()) {
t->setProperty("multicam_output",
watcher->GetTicket()->property("multicam_output"));
t->Finish(watcher->Get());
watcher->get_ticket()->property("multicam_output"));
t->finish(watcher->get());
} else {
t->Finish();
t->finish();
}
}
@@ -301,139 +301,139 @@ void PreviewAutoCacher::VideoRendered()
// viewer switch, so we'll completely ignore this watcher
if (running_video_tasks_.removeOne(watcher)) {
// Assume that a "result" is a fully completed image and a non-result is a cancelled ticket
if (watcher->HasResult()) {
if (watcher->GetTicket()->property("cached").toBool()) {
if (FrameHashCache *cache = QtUtils::ValueToPtr<FrameHashCache>(
if (watcher->has_result()) {
if (watcher->get_ticket()->property("cached").toBool()) {
if (FrameHashCache *cache = QtUtils::value_to_ptr<FrameHashCache>(
watcher->property("cache"))) {
rational time = watcher->property("time").value<rational>();
Rational time = watcher->property("time").value<Rational>();
JobTime job = watcher->property("job").value<JobTime>();
if (video_cache_data_.value(cache).job_tracker.isCurrent(
time, job)) {
cache->ValidateTime(time);
cache->validate_time(time);
}
}
}
}
// Continue rendering
TryRender();
try_render();
}
delete watcher;
}
void PreviewAutoCacher::ConnectToNodeCache(Node *node)
void PreviewAutoCacher::connect_to_node_cache(Node *node)
{
if (ignore_cache_requests_) {
return;
}
connect(node->video_frame_cache(), &PlaybackCache::Requested, this,
&PreviewAutoCacher::VideoInvalidatedFromCache);
connect(node->video_frame_cache(), &PlaybackCache::requested, this,
&PreviewAutoCacher::video_invalidated_from_cache);
connect(node->thumbnail_cache(), &PlaybackCache::Requested, this,
&PreviewAutoCacher::VideoInvalidatedFromCache);
connect(node->thumbnail_cache(), &PlaybackCache::requested, this,
&PreviewAutoCacher::video_invalidated_from_cache);
connect(node->audio_playback_cache(), &PlaybackCache::Requested, this,
&PreviewAutoCacher::AudioInvalidatedFromCache);
connect(node->audio_playback_cache(), &PlaybackCache::requested, this,
&PreviewAutoCacher::audio_invalidated_from_cache);
connect(node->waveform_cache(), &PlaybackCache::Requested, this,
&PreviewAutoCacher::AudioInvalidatedFromCache);
connect(node->waveform_cache(), &PlaybackCache::requested, this,
&PreviewAutoCacher::audio_invalidated_from_cache);
connect(node->video_frame_cache(), &PlaybackCache::CancelAll, this,
&PreviewAutoCacher::CancelForCache);
connect(node->video_frame_cache(), &PlaybackCache::cancel_all, this,
&PreviewAutoCacher::cancel_for_cache);
connect(node->audio_playback_cache(), &PlaybackCache::CancelAll, this,
&PreviewAutoCacher::CancelForCache);
connect(node->audio_playback_cache(), &PlaybackCache::cancel_all, this,
&PreviewAutoCacher::cancel_for_cache);
node->video_frame_cache()->ResignalRequests();
node->thumbnail_cache()->ResignalRequests();
node->audio_playback_cache()->ResignalRequests();
node->waveform_cache()->ResignalRequests();
node->video_frame_cache()->resignal_requests();
node->thumbnail_cache()->resignal_requests();
node->audio_playback_cache()->resignal_requests();
node->waveform_cache()->resignal_requests();
}
void PreviewAutoCacher::DisconnectFromNodeCache(Node *node)
void PreviewAutoCacher::disconnect_from_node_cache(Node *node)
{
disconnect(node->video_frame_cache(), &PlaybackCache::Requested, this,
&PreviewAutoCacher::VideoInvalidatedFromCache);
disconnect(node->video_frame_cache(), &PlaybackCache::requested, this,
&PreviewAutoCacher::video_invalidated_from_cache);
disconnect(node->thumbnail_cache(), &PlaybackCache::Requested, this,
&PreviewAutoCacher::VideoInvalidatedFromCache);
disconnect(node->thumbnail_cache(), &PlaybackCache::requested, this,
&PreviewAutoCacher::video_invalidated_from_cache);
disconnect(node->audio_playback_cache(), &PlaybackCache::Requested, this,
&PreviewAutoCacher::AudioInvalidatedFromCache);
disconnect(node->audio_playback_cache(), &PlaybackCache::requested, this,
&PreviewAutoCacher::audio_invalidated_from_cache);
disconnect(node->waveform_cache(), &PlaybackCache::Requested, this,
&PreviewAutoCacher::AudioInvalidatedFromCache);
disconnect(node->waveform_cache(), &PlaybackCache::requested, this,
&PreviewAutoCacher::audio_invalidated_from_cache);
disconnect(node->video_frame_cache(), &PlaybackCache::CancelAll, this,
&PreviewAutoCacher::CancelForCache);
disconnect(node->video_frame_cache(), &PlaybackCache::cancel_all, this,
&PreviewAutoCacher::cancel_for_cache);
disconnect(node->audio_playback_cache(), &PlaybackCache::CancelAll, this,
&PreviewAutoCacher::CancelForCache);
disconnect(node->audio_playback_cache(), &PlaybackCache::cancel_all, this,
&PreviewAutoCacher::cancel_for_cache);
}
void PreviewAutoCacher::CancelQueuedSingleFrameRender()
void PreviewAutoCacher::cancel_queued_single_frame_render()
{
if (single_frame_render_) {
// Signal that this ticket was cancelled with no value
single_frame_render_->Finish();
single_frame_render_->finish();
single_frame_render_ = nullptr;
}
}
void PreviewAutoCacher::StartCachingRange(const TimeRange &range,
void PreviewAutoCacher::start_caching_range(const TimeRange &range,
TimeRangeList *range_list,
RenderJobTracker *tracker)
{
range_list->insert(range);
tracker->insert(range, copier_->GetGraphChangeTime());
tracker->insert(range, copier_->get_graph_change_time());
}
void PreviewAutoCacher::StartCachingVideoRange(ViewerOutput *context,
void PreviewAutoCacher::start_caching_video_range(ViewerOutput *context,
PlaybackCache *cache,
const TimeRange &range)
{
Node *node = cache->parent();
rational using_tb;
Rational using_tb;
if (ThumbnailCache *thumbs = dynamic_cast<ThumbnailCache *>(cache)) {
using_tb = thumbs->GetTimebase();
using_tb = thumbs->get_timebase();
} else {
using_tb = context->GetVideoParams().frame_rate_as_time_base();
using_tb = context->get_video_params().frame_rate_as_time_base();
}
cache->ClearRequestRange(range);
cache->clear_request_range(range);
TimeRangeListFrameIterator iterator({ range }, using_tb);
pending_video_jobs_.push_back({ node, context, cache, range, iterator });
video_cache_data_[cache].job_tracker.insert(
TimeRange(iterator.Snap(range.in()), range.out()),
copier_->GetGraphChangeTime());
TryRender();
TimeRange(iterator.snap(range.in()), range.out()),
copier_->get_graph_change_time());
try_render();
}
void PreviewAutoCacher::StartCachingAudioRange(ViewerOutput *context,
void PreviewAutoCacher::start_caching_audio_range(ViewerOutput *context,
PlaybackCache *cache,
const TimeRange &range)
{
Node *node = cache->parent();
cache->ClearRequestRange(range);
cache->clear_request_range(range);
pending_audio_jobs_.push_back({ node, context, cache, range });
AudioCacheData &data = audio_cache_data_[cache];
data.context = context;
data.job_tracker.insert(range, copier_->GetGraphChangeTime());
TryRender();
data.job_tracker.insert(range, copier_->get_graph_change_time());
try_render();
}
void PreviewAutoCacher::VideoInvalidatedFromNode(ViewerOutput *context,
void PreviewAutoCacher::video_invalidated_from_node(ViewerOutput *context,
PlaybackCache *cache,
const TimeRange &range)
{
// Ignore render requests if no video is present
if (!context || !context->GetVideoParams().is_valid()) {
if (!context || !context->get_video_params().is_valid()) {
return;
}
@@ -441,20 +441,20 @@ void PreviewAutoCacher::VideoInvalidatedFromNode(ViewerOutput *context,
// want to dedicate all our rendering power to realtime feedback for the user
//CancelVideoTasks(node);
cache->ClearRequestRange(range);
cache->clear_request_range(range);
// If auto-cache is enabled and a slider is not being dragged, queue up to hash these frames
if (!NodeInputDragger::IsInputBeingDragged()) {
StartCachingVideoRange(context, cache, range);
if (!NodeInputDragger::is_input_being_dragged()) {
start_caching_video_range(context, cache, range);
}
}
void PreviewAutoCacher::AudioInvalidatedFromNode(ViewerOutput *context,
void PreviewAutoCacher::audio_invalidated_from_node(ViewerOutput *context,
PlaybackCache *cache,
const TimeRange &range)
{
// Ignore render requests if no video is present
if (!context || !context->GetAudioParams().is_valid()) {
if (!context || !context->get_audio_params().is_valid()) {
return;
}
@@ -462,54 +462,54 @@ void PreviewAutoCacher::AudioInvalidatedFromNode(ViewerOutput *context,
// cancelled, so some areas may end up unrendered forever
// ClearAudioQueue();
cache->ClearRequestRange(range);
cache->clear_request_range(range);
// If we're auto-caching audio or require realtime waveforms, we'll have to render this
StartCachingAudioRange(context, cache, range);
start_caching_audio_range(context, cache, range);
}
void PreviewAutoCacher::SetPlayhead(const rational &playhead)
void PreviewAutoCacher::set_playhead(const Rational &playhead)
{
cache_range_ =
TimeRange(playhead - OLIVE_CONFIG("DiskCacheBehind").value<rational>(),
playhead + OLIVE_CONFIG("DiskCacheAhead").value<rational>());
TimeRange(playhead - OAK_CONFIG("DiskCacheBehind").value<Rational>(),
playhead + OAK_CONFIG("DiskCacheAhead").value<Rational>());
TryRender();
try_render();
}
template <typename T> void CancelTasks(const T &task_list, bool and_wait)
template <typename T> void cancel_tasks(const T &task_list, bool and_wait)
{
for (auto it = task_list.cbegin(); it != task_list.cend(); it++) {
// Signal that the ticket should not be finished
(*it)->Cancel();
(*it)->cancel();
}
if (and_wait) {
// Wait for each ticket to finish
for (auto it = task_list.cbegin(); it != task_list.cend(); it++) {
(*it)->WaitForFinished();
(*it)->wait_for_finished();
}
}
}
void PreviewAutoCacher::CancelVideoTasks(bool and_wait_for_them_to_finish)
void PreviewAutoCacher::cancel_video_tasks(bool and_wait_for_them_to_finish)
{
CancelTasks(running_video_tasks_, and_wait_for_them_to_finish);
cancel_tasks(running_video_tasks_, and_wait_for_them_to_finish);
}
void PreviewAutoCacher::CancelAudioTasks(bool and_wait_for_them_to_finish)
void PreviewAutoCacher::cancel_audio_tasks(bool and_wait_for_them_to_finish)
{
CancelTasks(running_audio_tasks_, and_wait_for_them_to_finish);
cancel_tasks(running_audio_tasks_, and_wait_for_them_to_finish);
}
bool PreviewAutoCacher::IsRenderingCustomRange() const
bool PreviewAutoCacher::is_rendering_custom_range() const
{
if (!use_custom_range_) {
return false;
}
for (const VideoJob &job : pending_video_jobs_) {
if (job.range == custom_autocache_range_ && job.iterator.HasNext()) {
if (job.range == custom_autocache_range_ && job.iterator.has_next()) {
return true;
}
}
@@ -517,27 +517,27 @@ bool PreviewAutoCacher::IsRenderingCustomRange() const
return false;
}
void PreviewAutoCacher::SetRendersPaused(bool e)
void PreviewAutoCacher::set_renders_paused(bool e)
{
pause_renders_ = e;
if (!e) {
TryRender();
try_render();
}
}
void PreviewAutoCacher::SetThumbnailsPaused(bool e)
void PreviewAutoCacher::set_thumbnails_paused(bool e)
{
pause_thumbnails_ = e;
if (!e) {
TryRender();
try_render();
}
}
void PreviewAutoCacher::TryRender()
void PreviewAutoCacher::try_render()
{
delayed_requeue_timer_.stop();
if (copier_->HasUpdatesInQueue()) {
if (copier_->has_updates_in_queue()) {
// Check if we have jobs running in other threads that shouldn't be interrupted right now
// NOTE: We don't check for downloads because, while they run in another thread, they don't
// require any access to the graph and therefore don't risk race conditions.
@@ -547,7 +547,7 @@ void PreviewAutoCacher::TryRender()
}
// No jobs are active, we can process the update queue
copier_->ProcessUpdateQueue();
copier_->process_update_queue();
}
if (single_frame_render_) {
@@ -557,13 +557,13 @@ void PreviewAutoCacher::TryRender()
single_frame_render_ = nullptr;
// Check if already caching this
Node *n = QtUtils::ValueToPtr<Node>(t->property("node"));
Node *copy = copier_->GetCopy(n);
Node *n = QtUtils::value_to_ptr<Node>(t->property("node"));
Node *copy = copier_->get_copy(n);
if (copy) {
RenderTicketWatcher *watcher = RenderFrame(
copy, QtUtils::ValueToPtr<ViewerOutput>(t->property("viewer")),
t->property("time").value<rational>(), nullptr,
RenderTicketWatcher *watcher = render_frame(
copy, QtUtils::value_to_ptr<ViewerOutput>(t->property("viewer")),
t->property("time").value<Rational>(), nullptr,
t->property("dry").toBool());
if (watcher) {
video_immediate_passthroughs_[watcher].append(t);
@@ -587,19 +587,19 @@ void PreviewAutoCacher::TryRender()
while (!pending_video_jobs_.empty()) {
VideoJob &d = pending_video_jobs_.front();
if (Node *copy = copier_->GetCopy(d.node)) {
if (Node *copy = copier_->get_copy(d.node)) {
// Queue next frames
rational t;
Rational t;
while (running_video_tasks_.size() < max_tasks &&
d.iterator.GetNext(&t)) {
RenderFrame(copy, d.context, t, d.cache, false);
d.iterator.get_next(&t)) {
render_frame(copy, d.context, t, d.cache, false);
emit SignalCacheProxyTaskProgress(
emit signal_cache_proxy_task_progress(
double(d.iterator.frame_index()) /
double(d.iterator.size()));
if (!d.iterator.HasNext()) {
emit StopCacheProxyTasks();
if (!d.iterator.has_next()) {
emit stop_cache_proxy_tasks();
}
}
} else {
@@ -611,7 +611,7 @@ void PreviewAutoCacher::TryRender()
break;
}
if (d.iterator.HasNext()) {
if (d.iterator.has_next()) {
break;
} else {
pending_video_jobs_.pop_front();
@@ -627,14 +627,14 @@ void PreviewAutoCacher::TryRender()
bool pop = true;
// Start job
if (Node *copy = copier_->GetCopy(d.node)) {
if (Node *copy = copier_->get_copy(d.node)) {
TimeRange &queued_range = d.range;
TimeRange use_range = queued_range;
if (dynamic_cast<AudioWaveformCache *>(d.cache)) {
rational new_out = std::min(
Rational new_out = std::min(
use_range.in() +
AudioVisualWaveform::kMinimumSampleRate.flipped(),
AudioVisualWaveform::k_minimum_sample_rate.flipped(),
use_range.out());
if (new_out != use_range.out()) {
@@ -644,7 +644,7 @@ void PreviewAutoCacher::TryRender()
}
}
RenderAudio(copy, d.context, use_range, d.cache);
render_audio(copy, d.context, use_range, d.cache);
} else {
qWarning()
<< "Failed to find node copy for audio job, retrying";
@@ -662,65 +662,65 @@ void PreviewAutoCacher::TryRender()
}
}
RenderTicketWatcher *PreviewAutoCacher::RenderFrame(Node *node,
RenderTicketWatcher *PreviewAutoCacher::render_frame(Node *node,
ViewerOutput *context,
const rational &time,
const Rational &time,
PlaybackCache *cache,
bool dry)
{
RenderTicketWatcher *watcher = new RenderTicketWatcher();
watcher->setProperty("job",
QVariant::fromValue(copier_->GetLastUpdateTime()));
watcher->setProperty("cache", QtUtils::PtrToValue(cache));
QVariant::fromValue(copier_->get_last_update_time()));
watcher->setProperty("cache", QtUtils::ptr_to_value(cache));
watcher->setProperty("time", QVariant::fromValue(time));
connect(watcher, &RenderTicketWatcher::Finished, this,
&PreviewAutoCacher::VideoRendered);
connect(watcher, &RenderTicketWatcher::finished, this,
&PreviewAutoCacher::video_rendered);
running_video_tasks_.append(watcher);
RenderManager::RenderVideoParams rvp(node, context->GetVideoParams(),
context->GetAudioParams(), time,
RenderManager::RenderVideoParams rvp(node, context->get_video_params(),
context->get_audio_params(), time,
copied_color_manager_,
RenderMode::kOffline);
RenderMode::k_offline);
if (FrameHashCache *frame_cache = dynamic_cast<FrameHashCache *>(cache)) {
if (ThumbnailCache *wave_cache =
dynamic_cast<ThumbnailCache *>(cache)) {
Q_UNUSED(wave_cache)
rvp.video_params.set_divider(
VideoParams::GetDividerForTargetResolution(
VideoParams::get_divider_for_target_resolution(
rvp.video_params.width(), rvp.video_params.height(), 160,
120));
rvp.force_format = PixelFormat::F32;
rvp.force_channel_count = VideoParams::kRGBAChannelCount;
rvp.force_format = PixelFormat::f32;
rvp.force_channel_count = VideoParams::k_rgba_channel_count;
} else {
frame_cache->SetTimebase(
context->GetVideoParams().frame_rate_as_time_base());
frame_cache->set_timebase(
context->get_video_params().frame_rate_as_time_base());
}
rvp.AddCache(frame_cache);
rvp.add_cache(frame_cache);
} else {
// Preview/display frames are rendered at reduced precision to cut the
// GPU->CPU readback and IPC transfer bandwidth. The internal render
// pipeline stays F32/ACEScg; the final preview copy is packed 10-bit
// RGBA (4 bytes/pixel) to preserve 10-bit panel precision while halving
// bandwidth compared to F16.
rvp.force_format = PixelFormat::U10;
rvp.force_channel_count = VideoParams::kRGBAChannelCount;
rvp.force_format = PixelFormat::u10;
rvp.force_channel_count = VideoParams::k_rgba_channel_count;
}
// Video playback frames are rendered out-of-process. GPU textures cannot be
// shared across worker processes (or across independent Vulkan instances),
// so we always request CPU frames.
rvp.return_type = dry ? RenderManager::kNull : RenderManager::kFrame;
rvp.return_type = dry ? RenderManager::k_null : RenderManager::k_frame;
// Allow using cached images for this render job
rvp.use_cache = true;
// Multicam
rvp.multicam = copier_->GetCopy(multicam_);
rvp.multicam = copier_->get_copy(multicam_);
watcher->SetTicket(RenderManager::instance()->RenderFrame(rvp));
watcher->set_ticket(RenderManager::instance()->render_frame(rvp));
// If the ticket finished synchronously, VideoRendered has already deleted the
// watcher. The caller must not use this pointer in that case.
@@ -731,47 +731,47 @@ RenderTicketWatcher *PreviewAutoCacher::RenderFrame(Node *node,
return watcher;
}
RenderTicketPtr PreviewAutoCacher::RenderAudio(Node *node,
RenderTicketPtr PreviewAutoCacher::render_audio(Node *node,
ViewerOutput *context,
const TimeRange &r,
PlaybackCache *cache)
{
RenderTicketWatcher *watcher = new RenderTicketWatcher();
watcher->setProperty("job",
QVariant::fromValue(copier_->GetLastUpdateTime()));
watcher->setProperty("node", QtUtils::PtrToValue(node));
watcher->setProperty("cache", QtUtils::PtrToValue(cache));
QVariant::fromValue(copier_->get_last_update_time()));
watcher->setProperty("node", QtUtils::ptr_to_value(node));
watcher->setProperty("cache", QtUtils::ptr_to_value(cache));
watcher->setProperty("time", QVariant::fromValue(r));
connect(watcher, &RenderTicketWatcher::Finished, this,
&PreviewAutoCacher::AudioRendered);
connect(watcher, &RenderTicketWatcher::finished, this,
&PreviewAutoCacher::audio_rendered);
running_audio_tasks_.append(watcher);
AudioParams p = context->GetAudioParams();
AudioParams p = context->get_audio_params();
const bool invalid_params =
(p.sample_rate() <= 0 || p.channel_count() <= 0);
if (invalid_params) {
AudioParams fallback(
OLIVE_CONFIG("DefaultSequenceAudioFrequency").toInt(),
OLIVE_CONFIG("DefaultSequenceAudioLayout").toULongLong(),
ViewerOutput::kDefaultSampleFormat);
OAK_CONFIG("DefaultSequenceAudioFrequency").toInt(),
OAK_CONFIG("DefaultSequenceAudioLayout").toULongLong(),
ViewerOutput::k_default_sample_format);
p = fallback;
}
p.set_format(ViewerOutput::kDefaultSampleFormat);
p.set_format(ViewerOutput::k_default_sample_format);
RenderManager::RenderAudioParams rap(node, r, p, RenderMode::kOffline);
RenderManager::RenderAudioParams rap(node, r, p, RenderMode::k_offline);
rap.generate_waveforms = dynamic_cast<AudioWaveformCache *>(cache);
rap.clamp = false;
RenderTicketPtr ticket = RenderManager::instance()->RenderAudio(rap);
watcher->SetTicket(ticket);
RenderTicketPtr ticket = RenderManager::instance()->render_audio(rap);
watcher->set_ticket(ticket);
return ticket;
}
void PreviewAutoCacher::ConformFinished()
void PreviewAutoCacher::conform_finished()
{
// Got an audio conform, requeue all the audio currently needing a conform
last_conform_task_.Acquire();
last_conform_task_.acquire();
for (auto it = audio_cache_data_.begin(); it != audio_cache_data_.end();
it++) {
@@ -780,30 +780,30 @@ void PreviewAutoCacher::ConformFinished()
}
for (const TimeRange &range : it.value().needs_conform) {
it.key()->Request(it.value().context, range);
it.key()->request(it.value().context, range);
}
it.value().needs_conform.clear();
}
}
void PreviewAutoCacher::CacheProxyTaskCancelled()
void PreviewAutoCacher::cache_proxy_task_cancelled()
{
pending_video_jobs_.clear();
TryRender();
try_render();
}
void PreviewAutoCacher::ForceCacheRange(ViewerOutput *context,
void PreviewAutoCacher::force_cache_range(ViewerOutput *context,
const TimeRange &range)
{
use_custom_range_ = true;
custom_autocache_range_ = range;
// Re-hash these frames and start rendering
StartCachingVideoRange(context, context->video_frame_cache(), range);
start_caching_video_range(context, context->video_frame_cache(), range);
}
void PreviewAutoCacher::SetProject(Project *project)
void PreviewAutoCacher::set_project(Project *project)
{
if (project_ == project) {
return;
@@ -819,31 +819,31 @@ void PreviewAutoCacher::SetProject(Project *project)
// Handle video rendering tasks
if (!running_video_tasks_.isEmpty()) {
// Cancel any video tasks and wait for them to finish
CancelVideoTasks(true);
cancel_video_tasks(true);
running_video_tasks_.clear();
}
// Handle audio rendering tasks
if (!running_audio_tasks_.isEmpty()) {
// Cancel any audio tasks and wait for them to finish
CancelAudioTasks(true);
cancel_audio_tasks(true);
running_audio_tasks_.clear();
}
// Clear any single frame render that might be queued
CancelQueuedSingleFrameRender();
cancel_queued_single_frame_render();
// Not interested in video passthroughs anymore
video_immediate_passthroughs_.clear();
// Disconnect from all node cache's
for (auto it = copier_->GetNodeMap().cbegin();
it != copier_->GetNodeMap().cend(); it++) {
DisconnectFromNodeCache(it.key());
for (auto it = copier_->get_node_map().cbegin();
it != copier_->get_node_map().cend(); it++) {
disconnect_from_node_cache(it.key());
}
// Delete all of our copied nodes
copier_->SetProject(nullptr);
copier_->set_project(nullptr);
// Ensure all cache data is cleared
video_cache_data_.clear();
@@ -857,18 +857,18 @@ void PreviewAutoCacher::SetProject(Project *project)
if (project_) {
// Copy graph (this should always be a Project)
SetRendersPaused(true);
set_renders_paused(true);
copier_->SetProject(project_);
copier_->set_project(project_);
for (int i = 0; i < project_->nodes().size(); i++) {
project_->nodes().at(i)->ConnectedToPreviewEvent();
}
// Find copied viewer node
copied_color_manager_ = copier_->GetCopiedProject()->color_manager();
copied_color_manager_ = copier_->get_copied_project()->color_manager();
SetRendersPaused(false);
set_renders_paused(false);
}
}
+41 -41
View File
@@ -19,8 +19,8 @@
***/
#ifndef AUTOCACHER_H
#define AUTOCACHER_H
#ifndef OAK_AUTOCACHER_H
#define OAK_AUTOCACHER_H
#include <QtConcurrent/QtConcurrent>
@@ -49,20 +49,20 @@ public:
virtual ~PreviewAutoCacher() override;
RenderTicketPtr GetSingleFrame(ViewerOutput *viewer, const rational &t,
RenderTicketPtr get_single_frame(ViewerOutput *viewer, const Rational &t,
bool dry = false);
RenderTicketPtr GetSingleFrame(Node *n, ViewerOutput *viewer,
const rational &t, bool dry = false);
RenderTicketPtr get_single_frame(Node *n, ViewerOutput *viewer,
const Rational &t, bool dry = false);
RenderTicketPtr GetRangeOfAudio(ViewerOutput *viewer, TimeRange range);
RenderTicketPtr get_range_of_audio(ViewerOutput *viewer, TimeRange range);
void ClearSingleFrameRenders();
void ClearSingleFrameRendersThatArentRunning();
void clear_single_frame_renders();
void clear_single_frame_renders_that_arent_running();
/**
* @brief Set the viewer node to auto-cache
*/
void SetProject(Project *project);
void set_project(Project *project);
/**
* @brief Force a certain range to be cached
@@ -71,12 +71,12 @@ public:
* times they may want certain non-playhead-related time ranges to be cached (i.e. entire sequence
* or in/out range), so that can be set here.
*/
void ForceCacheRange(ViewerOutput *context, const TimeRange &range);
void force_cache_range(ViewerOutput *context, const TimeRange &range);
/**
* @brief Updates the range of frames to auto-cache
*/
void SetPlayhead(const rational &playhead);
void set_playhead(const Rational &playhead);
/**
* @brief Call cancel on all currently running video tasks
@@ -86,60 +86,60 @@ public:
* up finishing the task. The RenderManager will also return "no result", which can be checked
* with watcher->HasResult.
*/
void CancelVideoTasks(bool and_wait_for_them_to_finish = false);
void CancelAudioTasks(bool and_wait_for_them_to_finish = false);
void cancel_video_tasks(bool and_wait_for_them_to_finish = false);
void cancel_audio_tasks(bool and_wait_for_them_to_finish = false);
bool IsRenderingCustomRange() const;
bool is_rendering_custom_range() const;
void SetRendersPaused(bool e);
void SetThumbnailsPaused(bool e);
void set_renders_paused(bool e);
void set_thumbnails_paused(bool e);
void SetMulticamNode(MultiCamNode *n)
void set_multicam_node(MultiCamNode *n)
{
multicam_ = n;
}
void SetIgnoreCacheRequests(bool e)
void set_ignore_cache_requests(bool e)
{
ignore_cache_requests_ = e;
}
public slots:
void SetDisplayColorProcessor(ColorProcessorPtr processor)
void set_display_color_processor(ColorProcessorPtr processor)
{
display_color_processor_ = processor;
}
signals:
void StopCacheProxyTasks();
void stop_cache_proxy_tasks();
void SignalCacheProxyTaskProgress(double d);
void signal_cache_proxy_task_progress(double d);
private:
void TryRender();
void try_render();
RenderTicketWatcher *RenderFrame(Node *node, ViewerOutput *context,
const rational &time, PlaybackCache *cache,
RenderTicketWatcher *render_frame(Node *node, ViewerOutput *context,
const Rational &time, PlaybackCache *cache,
bool dry);
RenderTicketPtr RenderAudio(Node *node, ViewerOutput *context,
RenderTicketPtr render_audio(Node *node, ViewerOutput *context,
const TimeRange &range, PlaybackCache *cache);
void ConnectToNodeCache(Node *node);
void DisconnectFromNodeCache(Node *node);
void connect_to_node_cache(Node *node);
void disconnect_from_node_cache(Node *node);
void CancelQueuedSingleFrameRender();
void cancel_queued_single_frame_render();
void StartCachingRange(const TimeRange &range, TimeRangeList *range_list,
void start_caching_range(const TimeRange &range, TimeRangeList *range_list,
RenderJobTracker *tracker);
void StartCachingVideoRange(ViewerOutput *context, PlaybackCache *cache,
void start_caching_video_range(ViewerOutput *context, PlaybackCache *cache,
const TimeRange &range);
void StartCachingAudioRange(ViewerOutput *context, PlaybackCache *cache,
void start_caching_audio_range(ViewerOutput *context, PlaybackCache *cache,
const TimeRange &range);
void VideoInvalidatedFromNode(ViewerOutput *context, PlaybackCache *cache,
void video_invalidated_from_node(ViewerOutput *context, PlaybackCache *cache,
const olive::TimeRange &range);
void AudioInvalidatedFromNode(ViewerOutput *context, PlaybackCache *cache,
void audio_invalidated_from_node(ViewerOutput *context, PlaybackCache *cache,
const olive::TimeRange &range);
Project *project_;
@@ -208,37 +208,37 @@ private slots:
/**
* @brief Handler for when the NodeGraph reports a video change over a certain time range
*/
void VideoInvalidatedFromCache(ViewerOutput *context,
void video_invalidated_from_cache(ViewerOutput *context,
const olive::TimeRange &range);
/**
* @brief Handler for when the NodeGraph reports a audio change over a certain time range
*/
void AudioInvalidatedFromCache(ViewerOutput *context,
void audio_invalidated_from_cache(ViewerOutput *context,
const olive::TimeRange &range);
void CancelForCache();
void cancel_for_cache();
/**
* @brief Handler for when the RenderManager has returned rendered audio
*/
void AudioRendered();
void audio_rendered();
/**
* @brief Handler for when the RenderManager has returned rendered video frames
*/
void VideoRendered();
void video_rendered();
/**
* @brief Generic function called whenever the frames to render need to be (re)queued
*/
//void RequeueFrames();
void ConformFinished();
void conform_finished();
void CacheProxyTaskCancelled();
void cache_proxy_task_cancelled();
};
}
#endif // AUTOCACHER_H
#endif // OAK_AUTOCACHER_H
+103 -103
View File
@@ -35,7 +35,7 @@ ProjectCopier::ProjectCopier(QObject *parent)
copy_->setParent(this);
}
void ProjectCopier::SetProject(Project *project)
void ProjectCopier::set_project(Project *project)
{
if (original_) {
// Clear current project
@@ -44,20 +44,20 @@ void ProjectCopier::SetProject(Project *project)
copy_map_.clear();
graph_update_queue_.clear();
disconnect(original_, &Project::NodeAdded, this,
&ProjectCopier::QueueNodeAdd);
disconnect(original_, &Project::NodeRemoved, this,
&ProjectCopier::QueueNodeRemove);
disconnect(original_, &Project::InputConnected, this,
&ProjectCopier::QueueEdgeAdd);
disconnect(original_, &Project::InputDisconnected, this,
&ProjectCopier::QueueEdgeRemove);
disconnect(original_, &Project::ValueChanged, this,
&ProjectCopier::QueueValueChange);
disconnect(original_, &Project::InputValueHintChanged, this,
&ProjectCopier::QueueValueHintChange);
disconnect(original_, &Project::SettingChanged, this,
&ProjectCopier::QueueProjectSettingChange);
disconnect(original_, &Project::node_added, this,
&ProjectCopier::queue_node_add);
disconnect(original_, &Project::node_removed, this,
&ProjectCopier::queue_node_remove);
disconnect(original_, &Project::input_connected, this,
&ProjectCopier::queue_edge_add);
disconnect(original_, &Project::input_disconnected, this,
&ProjectCopier::queue_edge_remove);
disconnect(original_, &Project::value_changed, this,
&ProjectCopier::queue_value_change);
disconnect(original_, &Project::input_value_hint_changed, this,
&ProjectCopier::queue_value_hint_change);
disconnect(original_, &Project::setting_changed, this,
&ProjectCopier::queue_project_setting_change);
}
original_ = project;
@@ -70,49 +70,49 @@ void ProjectCopier::SetProject(Project *project)
// Add all nodes
for (int i = 0; i < copy_->nodes().size(); i++) {
InsertIntoCopyMap(original_->nodes().at(i), copy_->nodes().at(i));
insert_into_copy_map(original_->nodes().at(i), copy_->nodes().at(i));
}
for (int i = copy_->nodes().size(); i < original_->nodes().size();
i++) {
DoNodeAdd(original_->nodes().at(i));
do_node_add(original_->nodes().at(i));
}
// Add all connections
foreach (Node *node, original_->nodes()) {
for (auto it = node->input_connections().cbegin();
it != node->input_connections().cend(); it++) {
DoEdgeAdd(it->second, it->first);
do_edge_add(it->second, it->first);
}
}
// Copy project settings
Project::CopySettings(original_, copy_);
Project::copy_settings(original_, copy_);
// Ensure graph change value is just before the sync value
UpdateGraphChangeValue();
UpdateLastSyncedValue();
update_graph_change_value();
update_last_synced_value();
// Connect signals for future node additions/deletions
connect(original_, &Project::NodeAdded, this,
&ProjectCopier::QueueNodeAdd, Qt::DirectConnection);
connect(original_, &Project::NodeRemoved, this,
&ProjectCopier::QueueNodeRemove, Qt::DirectConnection);
connect(original_, &Project::InputConnected, this,
&ProjectCopier::QueueEdgeAdd, Qt::DirectConnection);
connect(original_, &Project::InputDisconnected, this,
&ProjectCopier::QueueEdgeRemove, Qt::DirectConnection);
connect(original_, &Project::ValueChanged, this,
&ProjectCopier::QueueValueChange, Qt::DirectConnection);
connect(original_, &Project::InputValueHintChanged, this,
&ProjectCopier::QueueValueHintChange, Qt::DirectConnection);
connect(original_, &Project::SettingChanged, this,
&ProjectCopier::QueueProjectSettingChange,
connect(original_, &Project::node_added, this,
&ProjectCopier::queue_node_add, Qt::DirectConnection);
connect(original_, &Project::node_removed, this,
&ProjectCopier::queue_node_remove, Qt::DirectConnection);
connect(original_, &Project::input_connected, this,
&ProjectCopier::queue_edge_add, Qt::DirectConnection);
connect(original_, &Project::input_disconnected, this,
&ProjectCopier::queue_edge_remove, Qt::DirectConnection);
connect(original_, &Project::value_changed, this,
&ProjectCopier::queue_value_change, Qt::DirectConnection);
connect(original_, &Project::input_value_hint_changed, this,
&ProjectCopier::queue_value_hint_change, Qt::DirectConnection);
connect(original_, &Project::setting_changed, this,
&ProjectCopier::queue_project_setting_change,
Qt::DirectConnection);
}
}
void ProjectCopier::ProcessUpdateQueue()
void ProjectCopier::process_update_queue()
{
bool copy_changed = false;
@@ -123,26 +123,26 @@ void ProjectCopier::ProcessUpdateQueue()
copy_changed = true;
switch (job.type) {
case QueuedJob::kNodeAdded:
DoNodeAdd(job.node);
case QueuedJob::k_node_added:
do_node_add(job.node);
break;
case QueuedJob::kNodeRemoved:
DoNodeRemove(job.node);
case QueuedJob::k_node_removed:
do_node_remove(job.node);
break;
case QueuedJob::kEdgeAdded:
DoEdgeAdd(job.output, job.input);
case QueuedJob::k_edge_added:
do_edge_add(job.output, job.input);
break;
case QueuedJob::kEdgeRemoved:
DoEdgeRemove(job.output, job.input);
case QueuedJob::k_edge_removed:
do_edge_remove(job.output, job.input);
break;
case QueuedJob::kValueChanged:
DoValueChange(job.input);
case QueuedJob::k_value_changed:
do_value_change(job.input);
break;
case QueuedJob::kValueHintChanged:
DoValueHintChange(job.input);
case QueuedJob::k_value_hint_changed:
do_value_hint_change(job.input);
break;
case QueuedJob::kProjectSettingChanged:
DoProjectSettingChange(job.key, job.value);
case QueuedJob::k_project_setting_changed:
do_project_setting_change(job.key, job.value);
break;
}
}
@@ -156,10 +156,10 @@ void ProjectCopier::ProcessUpdateQueue()
// Indicate that we have synchronized to this point, which is compared with the graph change
// time to see if our copied graph is up to date
UpdateLastSyncedValue();
update_last_synced_value();
}
void ProjectCopier::DoNodeAdd(Node *node)
void ProjectCopier::do_node_add(Node *node)
{
if (dynamic_cast<NodeGroup *>(node)) {
// Group nodes are just dummy nodes, no need to copy them
@@ -173,25 +173,25 @@ void ProjectCopier::DoNodeAdd(Node *node)
copy->setParent(copy_);
// Disable caches for copy
copy->SetCachesEnabled(false);
copy->set_caches_enabled(false);
// Copy cache UUIDs
copy->CopyCacheUuidsFrom(node);
copy->copy_cache_uuids_from(node);
// Insert into map
InsertIntoCopyMap(node, copy);
insert_into_copy_map(node, copy);
// Keep track of our nodes
created_nodes_.append(copy);
}
void ProjectCopier::DoNodeRemove(Node *node)
void ProjectCopier::do_node_remove(Node *node)
{
// Find our copy and remove it
Node *copy = copy_map_.take(node);
// Disconnect from node's caches
emit RemovedNode(node);
emit removed_node(node);
// Remove from created list
created_nodes_.removeOne(copy);
@@ -200,27 +200,27 @@ void ProjectCopier::DoNodeRemove(Node *node)
delete copy;
}
void ProjectCopier::DoEdgeAdd(Node *output, const NodeInput &input)
void ProjectCopier::do_edge_add(Node *output, const NodeInput &input)
{
// Create same connection with our copied graph
Node *our_output = copy_map_.value(output);
Node *our_input = copy_map_.value(input.node());
Node::ConnectEdge(our_output,
Node::connect_edge(our_output,
NodeInput(our_input, input.input(), input.element()));
}
void ProjectCopier::DoEdgeRemove(Node *output, const NodeInput &input)
void ProjectCopier::do_edge_remove(Node *output, const NodeInput &input)
{
// Remove same connection with our copied graph
Node *our_output = copy_map_.value(output);
Node *our_input = copy_map_.value(input.node());
Node::DisconnectEdge(our_output,
Node::disconnect_edge(our_output,
NodeInput(our_input, input.input(), input.element()));
}
void ProjectCopier::DoValueChange(const NodeInput &input)
void ProjectCopier::do_value_change(const NodeInput &input)
{
if (dynamic_cast<NodeGroup *>(input.node())) {
// Group nodes are just dummy nodes, no need to copy them
@@ -229,11 +229,11 @@ void ProjectCopier::DoValueChange(const NodeInput &input)
// Copy all values to our graph
Node *our_input = copy_map_.value(input.node());
Node::CopyValuesOfElement(input.node(), our_input, input.input(),
Node::copy_values_of_element(input.node(), our_input, input.input(),
input.element());
}
void ProjectCopier::DoValueHintChange(const NodeInput &input)
void ProjectCopier::do_value_hint_change(const NodeInput &input)
{
if (dynamic_cast<NodeGroup *>(input.node())) {
// Group nodes are just dummy nodes, no need to copy them
@@ -243,42 +243,42 @@ void ProjectCopier::DoValueHintChange(const NodeInput &input)
// Copy value hint to our graph
Node *our_input = copy_map_.value(input.node());
Node::ValueHint hint =
input.node()->GetValueHintForInput(input.input(), input.element());
our_input->SetValueHintForInput(input.input(), hint, input.element());
input.node()->get_value_hint_for_input(input.input(), input.element());
our_input->set_value_hint_for_input(input.input(), hint, input.element());
}
void ProjectCopier::DoProjectSettingChange(const QString &key,
void ProjectCopier::do_project_setting_change(const QString &key,
const QString &value)
{
copy_->SetSetting(key, value);
copy_->set_setting(key, value);
}
void ProjectCopier::InsertIntoCopyMap(Node *node, Node *copy)
void ProjectCopier::insert_into_copy_map(Node *node, Node *copy)
{
// Insert into map
copy_map_.insert(node, copy);
// Copy parameters
Node::CopyInputs(node, copy, false);
Node::copy_inputs(node, copy, false);
// Sync Footage proxy state (which is not stored as a Node input)
if (Footage *src_footage = dynamic_cast<Footage *>(node)) {
if (dynamic_cast<Footage *>(copy)) {
connect(src_footage, &Footage::ProxySettingsChanged, this,
connect(src_footage, &Footage::proxy_settings_changed, this,
[this, src_footage]() {
SyncFootageProxySettings(src_footage);
sync_footage_proxy_settings(src_footage);
});
SyncFootageProxySettings(src_footage);
sync_footage_proxy_settings(src_footage);
}
}
// Connect to node's cache
emit AddedNode(node);
emit added_node(node);
}
void ProjectCopier::SyncFootageProxySettings(Footage *source)
void ProjectCopier::sync_footage_proxy_settings(Footage *source)
{
Footage *copy = GetCopy(source);
Footage *copy = get_copy(source);
if (!copy) {
qWarning() << "ProjectCopier::SyncFootageProxySettings: no copy for"
<< source->filename();
@@ -289,9 +289,9 @@ void ProjectCopier::SyncFootageProxySettings(Footage *source)
<< "ProjectCopier::SyncFootageProxySettings:" << source->filename()
<< "enabled=" << source->proxy_enabled() << "->"
<< copy->proxy_enabled()
<< "state=" << ProxyManager::ProxyStateToString(source->proxy_state());
<< "state=" << ProxyManager::proxy_state_to_string(source->proxy_state());
copy->SetProxy(source->proxy_path(), source->proxy_state(),
copy->set_proxy(source->proxy_path(), source->proxy_state(),
source->proxy_video_stream_index(),
source->proxy_preset_version(), source->proxy_enabled());
@@ -300,35 +300,35 @@ void ProjectCopier::SyncFootageProxySettings(Footage *source)
}
}
void ProjectCopier::QueueNodeAdd(Node *node)
void ProjectCopier::queue_node_add(Node *node)
{
graph_update_queue_.push_back({ QueuedJob::kNodeAdded, node, NodeInput(),
graph_update_queue_.push_back({ QueuedJob::k_node_added, node, NodeInput(),
nullptr, QString(), QString() });
UpdateGraphChangeValue();
update_graph_change_value();
}
void ProjectCopier::QueueNodeRemove(Node *node)
void ProjectCopier::queue_node_remove(Node *node)
{
graph_update_queue_.push_back({ QueuedJob::kNodeRemoved, node, NodeInput(),
graph_update_queue_.push_back({ QueuedJob::k_node_removed, node, NodeInput(),
nullptr, QString(), QString() });
UpdateGraphChangeValue();
update_graph_change_value();
}
void ProjectCopier::QueueEdgeAdd(Node *output, const NodeInput &input)
void ProjectCopier::queue_edge_add(Node *output, const NodeInput &input)
{
graph_update_queue_.push_back({ QueuedJob::kEdgeAdded, nullptr, input,
graph_update_queue_.push_back({ QueuedJob::k_edge_added, nullptr, input,
output, QString(), QString() });
UpdateGraphChangeValue();
update_graph_change_value();
}
void ProjectCopier::QueueEdgeRemove(Node *output, const NodeInput &input)
void ProjectCopier::queue_edge_remove(Node *output, const NodeInput &input)
{
graph_update_queue_.push_back({ QueuedJob::kEdgeRemoved, nullptr, input,
graph_update_queue_.push_back({ QueuedJob::k_edge_removed, nullptr, input,
output, QString(), QString() });
UpdateGraphChangeValue();
update_graph_change_value();
}
void ProjectCopier::QueueValueChange(const NodeInput &input)
void ProjectCopier::queue_value_change(const NodeInput &input)
{
/*for (auto it = graph_update_queue_.begin(); it != graph_update_queue_.end(); ) {
if (it->type == QueuedJob::kValueChanged && it->input == input) {
@@ -338,34 +338,34 @@ void ProjectCopier::QueueValueChange(const NodeInput &input)
}
}*/
graph_update_queue_.push_back({ QueuedJob::kValueChanged, nullptr, input,
graph_update_queue_.push_back({ QueuedJob::k_value_changed, nullptr, input,
nullptr, QString(), QString() });
UpdateGraphChangeValue();
update_graph_change_value();
}
void ProjectCopier::QueueValueHintChange(const NodeInput &input)
void ProjectCopier::queue_value_hint_change(const NodeInput &input)
{
graph_update_queue_.push_back({ QueuedJob::kValueHintChanged, nullptr,
graph_update_queue_.push_back({ QueuedJob::k_value_hint_changed, nullptr,
input, nullptr, QString(), QString() });
UpdateGraphChangeValue();
update_graph_change_value();
}
void ProjectCopier::QueueProjectSettingChange(const QString &key,
void ProjectCopier::queue_project_setting_change(const QString &key,
const QString &value)
{
graph_update_queue_.push_back({ QueuedJob::kProjectSettingChanged, nullptr,
graph_update_queue_.push_back({ QueuedJob::k_project_setting_changed, nullptr,
NodeInput(), nullptr, key, value });
UpdateGraphChangeValue();
update_graph_change_value();
}
void ProjectCopier::UpdateGraphChangeValue()
void ProjectCopier::update_graph_change_value()
{
graph_changed_time_.Acquire();
graph_changed_time_.acquire();
}
void ProjectCopier::UpdateLastSyncedValue()
void ProjectCopier::update_last_synced_value()
{
last_update_time_.Acquire();
last_update_time_.acquire();
}
}
+39 -39
View File
@@ -19,8 +19,8 @@
***/
#ifndef PROJECTCOPIER_H
#define PROJECTCOPIER_H
#ifndef OAK_PROJECTCOPIER_H
#define OAK_PROJECTCOPIER_H
#include "node/project.h"
#include "node/project/footage/footage.h"
@@ -33,38 +33,38 @@ class ProjectCopier : public QObject {
public:
ProjectCopier(QObject *parent = nullptr);
void SetProject(Project *project);
void set_project(Project *project);
template <typename T> T *GetCopy(T *original)
template <typename T> T *get_copy(T *original)
{
return static_cast<T *>(copy_map_.value(original));
}
template <typename T> T *GetOriginal(T *copy)
template <typename T> T *get_original(T *copy)
{
return static_cast<T *>(copy_map_.key(copy));
}
Project *GetCopiedProject() const
Project *get_copied_project() const
{
return copy_;
}
const QHash<Node *, Node *> &GetNodeMap() const
const QHash<Node *, Node *> &get_node_map() const
{
return copy_map_;
}
const JobTime &GetGraphChangeTime() const
const JobTime &get_graph_change_time() const
{
return graph_changed_time_;
}
const JobTime &GetLastUpdateTime() const
const JobTime &get_last_update_time() const
{
return last_update_time_;
}
bool HasUpdatesInQueue() const
bool has_updates_in_queue() const
{
return !graph_update_queue_.empty();
}
@@ -75,27 +75,27 @@ public:
* PreviewAutoCacher staggers updates to its internal NodeGraph copy, only applying them when the
* RenderManager is not reading from it. This function is called when such an opportunity arises.
*/
void ProcessUpdateQueue();
void process_update_queue();
signals:
void AddedNode(Node *n);
void RemovedNode(Node *n);
void added_node(Node *n);
void removed_node(Node *n);
private:
void DoNodeAdd(Node *node);
void DoNodeRemove(Node *node);
void DoEdgeAdd(Node *output, const NodeInput &input);
void DoEdgeRemove(Node *output, const NodeInput &input);
void DoValueChange(const NodeInput &input);
void DoValueHintChange(const NodeInput &input);
void DoProjectSettingChange(const QString &key, const QString &value);
void do_node_add(Node *node);
void do_node_remove(Node *node);
void do_edge_add(Node *output, const NodeInput &input);
void do_edge_remove(Node *output, const NodeInput &input);
void do_value_change(const NodeInput &input);
void do_value_hint_change(const NodeInput &input);
void do_project_setting_change(const QString &key, const QString &value);
void SyncFootageProxySettings(Footage *source);
void sync_footage_proxy_settings(Footage *source);
void InsertIntoCopyMap(Node *node, Node *copy);
void insert_into_copy_map(Node *node, Node *copy);
void UpdateGraphChangeValue();
void UpdateLastSyncedValue();
void update_graph_change_value();
void update_last_synced_value();
Project *original_;
Project *copy_;
@@ -103,13 +103,13 @@ private:
class QueuedJob {
public:
enum Type {
kNodeAdded,
kNodeRemoved,
kEdgeAdded,
kEdgeRemoved,
kValueChanged,
kValueHintChanged,
kProjectSettingChanged
k_node_added,
k_node_removed,
k_edge_added,
k_edge_removed,
k_value_changed,
k_value_hint_changed,
k_project_setting_changed
};
Type type;
@@ -130,21 +130,21 @@ private:
JobTime last_update_time_;
private slots:
void QueueNodeAdd(Node *node);
void queue_node_add(Node *node);
void QueueNodeRemove(Node *node);
void queue_node_remove(Node *node);
void QueueEdgeAdd(Node *output, const NodeInput &input);
void queue_edge_add(Node *output, const NodeInput &input);
void QueueEdgeRemove(Node *output, const NodeInput &input);
void queue_edge_remove(Node *output, const NodeInput &input);
void QueueValueChange(const NodeInput &input);
void queue_value_change(const NodeInput &input);
void QueueValueHintChange(const NodeInput &input);
void queue_value_hint_change(const NodeInput &input);
void QueueProjectSettingChange(const QString &key, const QString &value);
void queue_project_setting_change(const QString &key, const QString &value);
};
}
#endif // PROJECTCOPIER_H
#endif // OAK_PROJECTCOPIER_H
+3 -3
View File
@@ -19,8 +19,8 @@
***/
#ifndef RENDERCACHE_H
#define RENDERCACHE_H
#ifndef OAK_RENDERCACHE_H
#define OAK_RENDERCACHE_H
#include "codec/decoder.h"
@@ -48,4 +48,4 @@ using ShaderCache = RenderCache<QString, QVariant>;
}
#endif // RENDERCACHE_H
#endif // OAK_RENDERCACHE_H
+22 -22
View File
@@ -43,12 +43,12 @@ Renderer::~Renderer()
}
}
TexturePtr Renderer::CreateTexture(const VideoParams &params, const void *data,
TexturePtr Renderer::create_texture(const VideoParams &params, const void *data,
int linesize)
{
QVariant v;
if (USE_TEXTURE_CACHE) {
if (use_texture_cache) {
QMutexLocker locker(&texture_cache_lock_);
for (auto it = texture_cache_.begin(); it != texture_cache_.end();
it++) {
@@ -65,25 +65,25 @@ TexturePtr Renderer::CreateTexture(const VideoParams &params, const void *data,
}
if (v.isNull()) {
v = CreateNativeTexture(params.effective_width(),
v = create_native_texture(params.effective_width(),
params.effective_height(),
params.effective_depth(), params.format(),
params.channel_count(), data, linesize);
} else if (data) {
UploadToTexture(v, params, data, linesize);
upload_to_texture(v, params, data, linesize);
} else {
this->Flush();
this->flush();
}
return CreateTextureFromNativeHandle(v, params);
return create_texture_from_native_handle(v, params);
}
void Renderer::DestroyTexture(Texture *texture)
void Renderer::destroy_texture(Texture *texture)
{
if (destroyed_) {
return;
}
if (USE_TEXTURE_CACHE) {
if (use_texture_cache) {
// HACK: Dirty, dirty hack. OpenGL uses "contexts" to store all of its data, and each context
// can only be used by the thread that created it. However there are also "shared contexts"
// where assets from one context can be used in another. We use shared contexts so that
@@ -109,28 +109,28 @@ void Renderer::DestroyTexture(Texture *texture)
texture_cache_lock_.unlock();
if (QThread::currentThread() == this->thread()) {
ClearOldTextures();
clear_old_textures();
}
} else {
DestroyNativeTexture(texture->id());
destroy_native_texture(texture->id());
}
}
QVariant Renderer::GetDefaultShader()
QVariant Renderer::get_default_shader()
{
QMutexLocker locker(&color_cache_mutex_);
if (default_shader_.isNull()) {
default_shader_ = CreateNativeShader(ShaderCode(QString(), QString()));
default_shader_ = create_native_shader(ShaderCode(QString(), QString()));
}
return default_shader_;
}
void Renderer::Destroy()
void Renderer::destroy()
{
if (!default_shader_.isNull()) {
DestroyNativeShader(default_shader_);
destroy_native_shader(default_shader_);
default_shader_.clear();
}
@@ -142,19 +142,19 @@ void Renderer::Destroy()
// be cleared while the renderer is still alive for those to be honored.
for (auto it = color_cache_.begin(); it != color_cache_.end(); it++) {
if (!it->compiled_shader.isNull()) {
DestroyNativeShader(it->compiled_shader);
destroy_native_shader(it->compiled_shader);
}
}
color_cache_.clear();
}
if (!interlace_texture_.isNull()) {
DestroyNativeShader(interlace_texture_);
destroy_native_shader(interlace_texture_);
interlace_texture_.clear();
}
for (auto it = texture_cache_.begin(); it != texture_cache_.end(); it++) {
DestroyNativeTexture(it->handle);
destroy_native_texture(it->handle);
}
texture_cache_.clear();
@@ -163,10 +163,10 @@ void Renderer::Destroy()
lifetime_->alive = false;
}
DestroyInternal();
destroy_internal();
}
TexturePtr Renderer::CreateTextureFromNativeHandle(const QVariant &v,
TexturePtr Renderer::create_texture_from_native_handle(const QVariant &v,
const VideoParams &params)
{
if (v.isNull()) {
@@ -176,14 +176,14 @@ TexturePtr Renderer::CreateTextureFromNativeHandle(const QVariant &v,
return std::make_shared<Texture>(this, v, params, lifetime_);
}
void Renderer::ClearOldTextures()
void Renderer::clear_old_textures()
{
QMutexLocker locker(&texture_cache_lock_);
for (auto it = texture_cache_.begin(); it != texture_cache_.end();) {
if (it->accessed <
QDateTime::currentMSecsSinceEpoch() - MAX_TEXTURE_LIFE) {
DestroyNativeTexture(it->handle);
QDateTime::currentMSecsSinceEpoch() - max_texture_life) {
destroy_native_texture(it->handle);
it = texture_cache_.erase(it);
} else {
it++;
+41 -41
View File
@@ -19,8 +19,8 @@
***/
#ifndef RENDERCONTEXT_H
#define RENDERCONTEXT_H
#ifndef OAK_RENDERCONTEXT_H
#define OAK_RENDERCONTEXT_H
#include <QMutex>
#include <QObject>
@@ -51,81 +51,81 @@ public:
Renderer(QObject *parent = nullptr);
virtual ~Renderer() override;
virtual bool Init() = 0;
virtual bool init() = 0;
TexturePtr CreateTexture(const VideoParams &params,
TexturePtr create_texture(const VideoParams &params,
const void *data = nullptr, int linesize = 0);
void DestroyTexture(Texture *texture);
void destroy_texture(Texture *texture);
virtual void BlitToTexture(QVariant shader, olive::AcceleratedJob &job,
virtual void blit_to_texture(QVariant shader, olive::AcceleratedJob &job,
olive::Texture *destination,
bool clear_destination = true)
{
Blit(shader, job, destination, destination->params(),
blit(shader, job, destination, destination->params(),
clear_destination);
}
void Blit(QVariant shader, olive::AcceleratedJob &job,
void blit(QVariant shader, olive::AcceleratedJob &job,
olive::VideoParams params, bool clear_destination = true)
{
Blit(shader, job, nullptr, params, clear_destination);
blit(shader, job, nullptr, params, clear_destination);
}
void BlitColorManaged(const ColorTransformJob &color_job,
void blit_color_managed(const ColorTransformJob &color_job,
Texture *destination, const VideoParams &params);
void BlitColorManaged(const ColorTransformJob &job, Texture *destination)
void blit_color_managed(const ColorTransformJob &job, Texture *destination)
{
BlitColorManaged(job, destination, destination->params());
blit_color_managed(job, destination, destination->params());
}
void BlitColorManaged(const ColorTransformJob &job,
void blit_color_managed(const ColorTransformJob &job,
const VideoParams &params)
{
BlitColorManaged(job, nullptr, params);
blit_color_managed(job, nullptr, params);
}
TexturePtr InterlaceTexture(TexturePtr top, TexturePtr bottom,
TexturePtr interlace_texture(TexturePtr top, TexturePtr bottom,
const VideoParams &params);
QVariant GetDefaultShader();
QVariant get_default_shader();
void Destroy();
void destroy();
virtual void PostDestroy() = 0;
virtual void post_destroy() = 0;
virtual void PostInit() = 0;
virtual void post_init() = 0;
virtual void ClearDestination(olive::Texture *texture = nullptr,
virtual void clear_destination(olive::Texture *texture = nullptr,
double r = 0.0, double g = 0.0,
double b = 0.0, double a = 1.0) = 0;
virtual QVariant CreateNativeShader(olive::ShaderCode code) = 0;
virtual QVariant create_native_shader(olive::ShaderCode code) = 0;
virtual void DestroyNativeShader(QVariant shader) = 0;
virtual void destroy_native_shader(QVariant shader) = 0;
virtual void UploadToTexture(const QVariant &handle,
virtual void upload_to_texture(const QVariant &handle,
const VideoParams &params, const void *data,
int linesize) = 0;
virtual void DownloadFromTexture(const QVariant &handle,
virtual void download_from_texture(const QVariant &handle,
const VideoParams &params, void *data,
int linesize) = 0;
virtual void Flush() = 0;
virtual void flush() = 0;
virtual Color GetPixelFromTexture(olive::Texture *texture,
virtual Color get_pixel_from_texture(olive::Texture *texture,
const QPointF &pt) = 0;
std::shared_ptr<RendererLifetime> GetLifetime() const
std::shared_ptr<RendererLifetime> get_lifetime() const
{
return lifetime_;
}
virtual bool IsOpenGL() const
virtual bool is_open_gl() const
{
return false;
}
virtual bool IsVulkan() const
virtual bool is_vulkan() const
{
return false;
}
@@ -137,7 +137,7 @@ public:
* Default implementation is a no-op. OpenGL-based renderers override this
* to bind the texture as a framebuffer render target.
*/
virtual void AttachOutputTexture(olive::Texture *texture)
virtual void attach_output_texture(olive::Texture *texture)
{
(void)texture;
}
@@ -147,23 +147,23 @@ public:
*
* Default implementation is a no-op.
*/
virtual void DetachOutputTexture()
virtual void detach_output_texture()
{
}
protected:
virtual void Blit(QVariant shader, olive::AcceleratedJob &job,
virtual void blit(QVariant shader, olive::AcceleratedJob &job,
olive::Texture *destination,
olive::VideoParams destination_params,
bool clear_destination) = 0;
virtual QVariant CreateNativeTexture(int width, int height, int depth,
virtual QVariant create_native_texture(int width, int height, int depth,
PixelFormat format, int channel_count,
const void *data = nullptr,
int linesize = 0) = 0;
virtual void DestroyNativeTexture(QVariant texture) = 0;
virtual void destroy_native_texture(QVariant texture) = 0;
virtual void DestroyInternal() = 0;
virtual void destroy_internal() = 0;
private:
std::atomic<bool> destroyed_{ false };
@@ -180,12 +180,12 @@ private:
QVector<LUT> lut1d_textures;
};
TexturePtr CreateTextureFromNativeHandle(const QVariant &v,
TexturePtr create_texture_from_native_handle(const QVariant &v,
const VideoParams &params);
bool GetColorContext(const ColorTransformJob &color_job, ColorContext *ctx);
bool get_color_context(const ColorTransformJob &color_job, ColorContext *ctx);
void ClearOldTextures();
void clear_old_textures();
QHash<QString, ColorContext> color_cache_;
@@ -199,8 +199,8 @@ private:
qint64 accessed;
};
static const int MAX_TEXTURE_LIFE = 5000;
static const bool USE_TEXTURE_CACHE = true;
static const int max_texture_life = 5000;
static const bool use_texture_cache = true;
std::list<CachedTexture> texture_cache_;
QMutex color_cache_mutex_;
@@ -214,4 +214,4 @@ private:
}
#endif // RENDERCONTEXT_H
#endif // OAK_RENDERCONTEXT_H
+5 -5
View File
@@ -46,11 +46,11 @@ void RenderJobTracker::clear()
jobs_.clear();
}
bool RenderJobTracker::isCurrent(const rational &time, JobTime job_time) const
bool RenderJobTracker::isCurrent(const Rational &time, JobTime job_time) const
{
for (auto it = jobs_.crbegin(); it != jobs_.crend(); it++) {
if (it->Contains(time)) {
return job_time >= it->GetJobTime();
if (it->contains(time)) {
return job_time >= it->get_job_time();
}
}
@@ -64,8 +64,8 @@ RenderJobTracker::getCurrentSubRanges(const TimeRange &range,
TimeRangeList current_ranges;
for (auto it = jobs_.crbegin(); it != jobs_.crend(); it++) {
if (job_time >= it->GetJobTime() && it->OverlapsWith(range)) {
current_ranges.insert(it->Intersected(range));
if (job_time >= it->get_job_time() && it->overlaps_with(range)) {
current_ranges.insert(it->intersected(range));
}
}
+6 -6
View File
@@ -19,8 +19,8 @@
***/
#ifndef RENDERJOBTRACKER_H
#define RENDERJOBTRACKER_H
#ifndef OAK_RENDERJOBTRACKER_H
#define OAK_RENDERJOBTRACKER_H
#include <olive/core/core.h>
@@ -40,7 +40,7 @@ public:
void clear();
bool isCurrent(const rational &time, JobTime job_time) const;
bool isCurrent(const Rational &time, JobTime job_time) const;
TimeRangeList getCurrentSubRanges(const TimeRange &range,
const JobTime &job_time) const;
@@ -55,11 +55,11 @@ private:
job_time_ = job_time;
}
JobTime GetJobTime() const
JobTime get_job_time() const
{
return job_time_;
}
void SetJobTime(JobTime jt)
void set_job_time(JobTime jt)
{
job_time_ = jt;
}
@@ -73,4 +73,4 @@ private:
}
#endif // RENDERJOBTRACKER_H
#endif // OAK_RENDERJOBTRACKER_H
+68 -68
View File
@@ -41,36 +41,36 @@ namespace olive
{
RenderManager *RenderManager::instance_ = nullptr;
const rational RenderManager::kDryRunInterval = rational(10);
const Rational RenderManager::k_dry_run_interval = Rational(10);
RenderManager::Backend RenderManager::BackendFromString(const QString &backend)
RenderManager::Backend RenderManager::backend_from_string(const QString &backend)
{
const QString lower = backend.toLower();
if (lower == QStringLiteral("vulkan")) {
return kVulkan;
return k_vulkan;
}
if (lower == QStringLiteral("multiprocess")) {
return kMultiProcess;
return k_multi_process;
}
if (lower == QStringLiteral("dummy")) {
return kDummy;
return k_dummy;
}
return kOpenGL;
return k_open_gl;
}
QString RenderManager::BackendToString(Backend backend)
QString RenderManager::backend_to_string(Backend backend)
{
switch (backend) {
case kOpenGL:
case k_open_gl:
return QStringLiteral("opengl");
case kVulkan:
case k_vulkan:
return QStringLiteral("vulkan");
case kMultiProcess:
case k_multi_process:
return QStringLiteral("multiprocess");
case kDummy:
case k_dummy:
return QStringLiteral("dummy");
}
@@ -78,12 +78,12 @@ QString RenderManager::BackendToString(Backend backend)
}
RenderManager::RenderManager(QObject *parent)
: backend_(BackendFromString(OLIVE_CONFIG("GraphicsBackend").toString()))
: backend_(backend_from_string(OAK_CONFIG("GraphicsBackend").toString()))
, requested_backend_(backend_)
, aggressive_gc_(0)
, worker_pool_(nullptr)
{
if (backend_ == kVulkan) {
if (backend_ == k_vulkan) {
#ifndef OAK_ENABLE_DYNAMIC_RENDER_BACKEND
qWarning()
<< "Vulkan backend requested but dynamic render backend is not enabled. Falling back to OpenGL.";
@@ -91,27 +91,27 @@ RenderManager::RenderManager(QObject *parent)
#endif
}
if (backend_ == kOpenGL || backend_ == kVulkan) {
if (backend_ == k_open_gl || backend_ == k_vulkan) {
#ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND
auto *dynamic_renderer =
new DynamicRenderer(BackendToString(requested_backend_));
if (!dynamic_renderer->Load()) {
new DynamicRenderer(backend_to_string(requested_backend_));
if (!dynamic_renderer->load()) {
qWarning() << "Failed to load dynamic render backend"
<< BackendToString(requested_backend_)
<< backend_to_string(requested_backend_)
<< ", falling back to OpenGL";
delete dynamic_renderer;
backend_ = kOpenGL;
backend_ = k_open_gl;
context_ = new OpenGLRenderer();
} else {
context_ = dynamic_renderer;
// DynamicRenderer may internally fall back (e.g. Vulkan -> OpenGL).
// Synchronize RenderManager's view of the actual runtime backend.
Backend actual_backend =
BackendFromString(dynamic_renderer->backend_name());
backend_from_string(dynamic_renderer->backend_name());
if (actual_backend != backend_) {
qWarning() << "Dynamic render backend fell back from"
<< BackendToString(backend_) << "to"
<< BackendToString(actual_backend);
<< backend_to_string(backend_) << "to"
<< backend_to_string(actual_backend);
backend_ = actual_backend;
}
}
@@ -127,26 +127,26 @@ RenderManager::RenderManager(QObject *parent)
}
if (context_) {
dry_run_thread_ = CreateThread();
audio_thread_ = CreateThread();
dry_run_thread_ = create_thread();
audio_thread_ = create_thread();
waveform_threads_.resize(QThread::idealThreadCount());
for (size_t i = 0; i < waveform_threads_.size(); i++) {
waveform_threads_[i] = CreateThread();
waveform_threads_[i] = create_thread();
}
auto_cacher_ = new PreviewAutoCacher(this);
worker_pool_ = new RenderWorkerPool(
decoder_cache_, BackendToString(requested_backend_), this);
decoder_cache_, backend_to_string(requested_backend_), this);
worker_pool_->start(QThread::NormalPriority);
backend_ = kMultiProcess;
backend_ = k_multi_process;
}
decoder_clear_timer_ = new QTimer(this);
decoder_clear_timer_->setInterval(kDecoderMaximumInactivity);
decoder_clear_timer_->setInterval(k_decoder_maximum_inactivity);
connect(decoder_clear_timer_, &QTimer::timeout, this,
&RenderManager::ClearOldDecoders);
&RenderManager::clear_old_decoders);
decoder_clear_timer_->start();
}
@@ -154,7 +154,7 @@ RenderManager::~RenderManager()
{
if (context_) {
if (worker_pool_) {
worker_pool_->Shutdown();
worker_pool_->shutdown();
delete worker_pool_;
worker_pool_ = nullptr;
}
@@ -167,12 +167,12 @@ RenderManager::~RenderManager()
rt->wait();
}
context_->PostDestroy();
context_->post_destroy();
delete context_;
}
}
RenderThread *RenderManager::CreateThread(Renderer *renderer)
RenderThread *RenderManager::create_thread(Renderer *renderer)
{
auto t = new RenderThread(renderer, decoder_cache_, shader_cache_, this);
render_threads_.push_back(t);
@@ -180,12 +180,12 @@ RenderThread *RenderManager::CreateThread(Renderer *renderer)
return t;
}
RenderTicketPtr RenderManager::RenderFrame(const RenderVideoParams &params)
RenderTicketPtr RenderManager::render_frame(const RenderVideoParams &params)
{
// Create ticket
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
ticket->setProperty("node", QtUtils::PtrToValue(params.node));
ticket->setProperty("node", QtUtils::ptr_to_value(params.node));
ticket->setProperty("time", QVariant::fromValue(params.time));
ticket->setProperty("size", params.force_size);
ticket->setProperty("matrix", params.force_matrix);
@@ -194,9 +194,9 @@ RenderTicketPtr RenderManager::RenderFrame(const RenderVideoParams &params)
ticket->setProperty("usecache", params.use_cache);
ticket->setProperty("channelcount", params.force_channel_count);
ticket->setProperty("mode", params.mode);
ticket->setProperty("type", kTypeVideo);
ticket->setProperty("type", k_type_video);
ticket->setProperty("colormanager",
QtUtils::PtrToValue(params.color_manager));
QtUtils::ptr_to_value(params.color_manager));
ticket->setProperty("coloroutput",
QVariant::fromValue(params.force_color_output));
ticket->setProperty("colortransform",
@@ -209,44 +209,44 @@ RenderTicketPtr RenderManager::RenderFrame(const RenderVideoParams &params)
ticket->setProperty("cachetimebase",
QVariant::fromValue(params.cache_timebase));
ticket->setProperty("cacheid", QVariant::fromValue(params.cache_id));
ticket->setProperty("multicam", QtUtils::PtrToValue(params.multicam));
ticket->setProperty("multicam", QtUtils::ptr_to_value(params.multicam));
// Video frames are always rendered by the worker pool. GPU textures cannot
// be shared across the process boundary (or across independent Vulkan
// instances), so texture-return requests are downgraded to CPU frames.
RenderVideoParams worker_params = params;
if (worker_params.return_type == ReturnType::kTexture) {
worker_params.return_type = ReturnType::kFrame;
if (worker_params.return_type == ReturnType::k_texture) {
worker_params.return_type = ReturnType::k_frame;
}
if (worker_params.return_type == ReturnType::kNull) {
if (worker_params.return_type == ReturnType::k_null) {
if (dry_run_thread_) {
dry_run_thread_->AddTicket(ticket);
dry_run_thread_->add_ticket(ticket);
} else {
// No render threads (e.g. dummy backend), finish without a result
ticket->Finish();
ticket->finish();
}
} else if (worker_pool_ &&
worker_pool_->SubmitFrame(ticket, worker_params)) {
worker_pool_->submit_frame(ticket, worker_params)) {
return ticket;
} else {
qWarning()
<< "RenderManager: worker pool unavailable, finishing ticket "
"without result";
ticket->Finish();
ticket->finish();
}
return ticket;
}
RenderTicketPtr RenderManager::RenderAudio(const RenderAudioParams &params)
RenderTicketPtr RenderManager::render_audio(const RenderAudioParams &params)
{
// Create ticket
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
ticket->setProperty("node", QtUtils::PtrToValue(params.node));
ticket->setProperty("node", QtUtils::ptr_to_value(params.node));
ticket->setProperty("time", QVariant::fromValue(params.range));
ticket->setProperty("type", kTypeAudio);
ticket->setProperty("type", k_type_audio);
ticket->setProperty("enablewaveforms", params.generate_waveforms);
ticket->setProperty("clamp", params.clamp);
ticket->setProperty("aparam", QVariant::fromValue(params.audio_params));
@@ -255,26 +255,26 @@ RenderTicketPtr RenderManager::RenderAudio(const RenderAudioParams &params)
if (params.generate_waveforms && !waveform_threads_.empty()) {
size_t thread_index = last_waveform_thread_ % waveform_threads_.size();
RenderThread *thread = waveform_threads_[thread_index];
thread->AddTicket(ticket);
thread->add_ticket(ticket);
last_waveform_thread_++;
} else if (audio_thread_) {
audio_thread_->AddTicket(ticket);
audio_thread_->add_ticket(ticket);
} else {
// No render threads (e.g. dummy backend), finish without a result
ticket->Finish();
ticket->finish();
}
return ticket;
}
bool RenderManager::RemoveTicket(RenderTicketPtr ticket)
bool RenderManager::remove_ticket(RenderTicketPtr ticket)
{
if (worker_pool_ && worker_pool_->RemoveTicket(ticket)) {
if (worker_pool_ && worker_pool_->remove_ticket(ticket)) {
return true;
}
for (RenderThread *rt : render_threads_) {
if (rt->RemoveTicket(ticket)) {
if (rt->remove_ticket(ticket)) {
return true;
}
}
@@ -282,7 +282,7 @@ bool RenderManager::RemoveTicket(RenderTicketPtr ticket)
return false;
}
void RenderManager::SetAggressiveGarbageCollection(bool enabled)
void RenderManager::set_aggressive_garbage_collection(bool enabled)
{
aggressive_gc_ += enabled ? 1 : -1;
@@ -292,13 +292,13 @@ void RenderManager::SetAggressiveGarbageCollection(bool enabled)
}
if (aggressive_gc_ > 0) {
decoder_clear_timer_->setInterval(kDecoderMaximumInactivityAggressive);
decoder_clear_timer_->setInterval(k_decoder_maximum_inactivity_aggressive);
} else {
decoder_clear_timer_->setInterval(kDecoderMaximumInactivity);
decoder_clear_timer_->setInterval(k_decoder_maximum_inactivity);
}
}
void RenderManager::ClearOldDecoders()
void RenderManager::clear_old_decoders()
{
if (!decoder_cache_) {
// No decoder cache exists on backends without a renderer (e.g. dummy)
@@ -308,13 +308,13 @@ void RenderManager::ClearOldDecoders()
QMutexLocker locker(decoder_cache_->mutex());
qint64 min_age =
QDateTime::currentMSecsSinceEpoch() - kDecoderMaximumInactivity;
QDateTime::currentMSecsSinceEpoch() - k_decoder_maximum_inactivity;
for (auto it = decoder_cache_->begin(); it != decoder_cache_->end();) {
DecoderPair decoder = it.value();
if (decoder.decoder->GetLastAccessedTime() < min_age) {
decoder.decoder->Close();
if (decoder.decoder->get_last_accessed_time() < min_age) {
decoder.decoder->close();
it = decoder_cache_->erase(it);
} else {
it++;
@@ -331,12 +331,12 @@ RenderThread::RenderThread(Renderer *renderer, DecoderCache *decoder_cache,
, shader_cache_(shader_cache)
{
if (context_) {
context_->Init();
context_->init();
context_->moveToThread(this);
}
}
void RenderThread::AddTicket(RenderTicketPtr ticket)
void RenderThread::add_ticket(RenderTicketPtr ticket)
{
QMutexLocker locker(&mutex_);
ticket->moveToThread(this);
@@ -344,7 +344,7 @@ void RenderThread::AddTicket(RenderTicketPtr ticket)
wait_.wakeOne();
}
bool RenderThread::RemoveTicket(RenderTicketPtr ticket)
bool RenderThread::remove_ticket(RenderTicketPtr ticket)
{
QMutexLocker locker(&mutex_);
@@ -367,7 +367,7 @@ void RenderThread::quit()
void RenderThread::run()
{
if (context_) {
context_->PostInit();
context_->post_init();
}
QMutexLocker locker(&mutex_);
@@ -388,12 +388,12 @@ void RenderThread::run()
locker.unlock();
// Setup the ticket for ::Process
ticket->Start();
ticket->start();
if (ticket->IsCancelled()) {
ticket->Finish();
if (ticket->is_cancelled()) {
ticket->finish();
} else {
RenderProcessor::Process(ticket, context_, decoder_cache_,
RenderProcessor::process(ticket, context_, decoder_cache_,
shader_cache_);
}
@@ -402,7 +402,7 @@ void RenderThread::run()
}
if (context_) {
context_->Destroy();
context_->destroy();
context_->moveToThread(this->thread());
}
}
+36 -36
View File
@@ -19,8 +19,8 @@
***/
#ifndef RENDERBACKEND_H
#define RENDERBACKEND_H
#ifndef OAK_RENDERBACKEND_H
#define OAK_RENDERBACKEND_H
#include <QtConcurrent/QtConcurrent>
@@ -45,9 +45,9 @@ public:
RenderThread(Renderer *renderer, DecoderCache *decoder_cache,
ShaderCache *shader_cache, QObject *parent = nullptr);
void AddTicket(RenderTicketPtr ticket);
void add_ticket(RenderTicketPtr ticket);
bool RemoveTicket(RenderTicketPtr ticket);
bool remove_ticket(RenderTicketPtr ticket);
void quit();
@@ -77,24 +77,24 @@ class RenderManager : public QObject {
public:
enum Backend {
/// Graphics acceleration provided by OpenGL
kOpenGL,
k_open_gl,
/// Vulkan requested by the user. Falls back to OpenGL until VulkanRenderer is implemented.
kVulkan,
k_vulkan,
/// Video frames are rendered by an external oak-render-worker process.
kMultiProcess,
k_multi_process,
/// No graphics rendering - used to test core threading logic
kDummy
k_dummy
};
static void CreateInstance()
static void create_instance()
{
instance_ = new RenderManager();
}
static void DestroyInstance()
static void destroy_instance()
{
delete instance_;
instance_ = nullptr;
@@ -105,11 +105,11 @@ public:
return instance_;
}
enum ReturnType { kTexture, kFrame, kNull };
enum ReturnType { k_texture, k_frame, k_null };
struct RenderVideoParams {
RenderVideoParams(Node *n, const VideoParams &vparam,
const AudioParams &aparam, const rational &t,
const AudioParams &aparam, const Rational &t,
ColorManager *colorman, RenderMode::Mode m)
{
node = n;
@@ -118,8 +118,8 @@ public:
time = t;
color_manager = colorman;
use_cache = false;
return_type = kFrame;
force_format = PixelFormat::INVALID;
return_type = k_frame;
force_format = PixelFormat::invalid;
force_color_output = nullptr;
force_color_transform = ColorTransform();
force_size = QSize(0, 0);
@@ -128,17 +128,17 @@ public:
multicam = nullptr;
}
void AddCache(FrameHashCache *cache)
void add_cache(FrameHashCache *cache)
{
cache_dir = cache->GetCacheDirectory();
cache_timebase = cache->GetTimebase();
cache_id = cache->GetUuid().toString();
cache_dir = cache->get_cache_directory();
cache_timebase = cache->get_timebase();
cache_id = cache->get_uuid().toString();
}
Node *node;
VideoParams video_params;
AudioParams audio_params;
rational time;
Rational time;
ColorManager *color_manager;
bool use_cache;
ReturnType return_type;
@@ -146,7 +146,7 @@ public:
MultiCamNode *multicam;
QString cache_dir;
rational cache_timebase;
Rational cache_timebase;
QString cache_id;
QSize force_size;
@@ -157,7 +157,7 @@ public:
ColorTransform force_color_transform;
};
static const rational kDryRunInterval;
static const Rational k_dry_run_interval;
/**
* @brief Asynchronously generate a frame at a given time
@@ -167,7 +167,7 @@ public:
*
* This function is thread-safe.
*/
RenderTicketPtr RenderFrame(const RenderVideoParams &params);
RenderTicketPtr render_frame(const RenderVideoParams &params);
struct RenderAudioParams {
RenderAudioParams(Node *n, const TimeRange &time,
@@ -196,11 +196,11 @@ public:
*
* This function is thread-safe.
*/
RenderTicketPtr RenderAudio(const RenderAudioParams &params);
RenderTicketPtr render_audio(const RenderAudioParams &params);
bool RemoveTicket(RenderTicketPtr ticket);
bool remove_ticket(RenderTicketPtr ticket);
enum TicketType { kTypeVideo, kTypeAudio };
enum TicketType { k_type_video, k_type_audio };
Backend backend() const
{
@@ -212,21 +212,21 @@ public:
return requested_backend_;
}
static Backend BackendFromString(const QString &backend);
static QString BackendToString(Backend backend);
static Backend backend_from_string(const QString &backend);
static QString backend_to_string(Backend backend);
PreviewAutoCacher *GetCacher() const
PreviewAutoCacher *get_cacher() const
{
return auto_cacher_;
}
void SetProject(Project *p)
void set_project(Project *p)
{
auto_cacher_->SetProject(p);
auto_cacher_->set_project(p);
}
public slots:
void SetAggressiveGarbageCollection(bool enabled);
void set_aggressive_garbage_collection(bool enabled);
signals:
@@ -235,7 +235,7 @@ private:
virtual ~RenderManager() override;
RenderThread *CreateThread(Renderer *renderer = nullptr);
RenderThread *create_thread(Renderer *renderer = nullptr);
static RenderManager *instance_;
@@ -248,8 +248,8 @@ private:
ShaderCache *shader_cache_ = nullptr;
static constexpr auto kDecoderMaximumInactivityAggressive = 1000;
static constexpr auto kDecoderMaximumInactivity = 5000;
static constexpr auto k_decoder_maximum_inactivity_aggressive = 1000;
static constexpr auto k_decoder_maximum_inactivity = 5000;
int aggressive_gc_ = 0;
@@ -268,11 +268,11 @@ private:
RenderWorkerPool *worker_pool_ = nullptr;
private slots:
void ClearOldDecoders();
void clear_old_decoders();
};
}
Q_DECLARE_METATYPE(olive::RenderManager::TicketType)
#endif // RENDERBACKEND_H
#endif // OAK_RENDERBACKEND_H
+5 -5
View File
@@ -19,8 +19,8 @@
***/
#ifndef RENDERMODE_H
#define RENDERMODE_H
#ifndef OAK_RENDERMODE_H
#define OAK_RENDERMODE_H
#include "common/define.h"
@@ -37,16 +37,16 @@ public:
* This render is for realtime preview ONLY and does not need to be "perfect". Nodes can use lower-accuracy functions
* to save performance when possible.
*/
kOffline,
k_offline,
/**
* This render is some sort of export or master copy and Nodes should take time/bandwidth/system resources to produce
* a higher accuracy version.
*/
kOnline
k_online
};
};
}
#endif // RENDERMODE_H
#endif // OAK_RENDERMODE_H
+190 -190
View File
@@ -34,8 +34,8 @@
#include "node/project.h"
#include "rendermanager.h"
#include "render/plugin/pluginrenderer.h"
#include "pluginSupport/OliveClip.h"
#include "pluginSupport/OliveHost.h"
#include "pluginSupport/oliveclip.h"
#include "pluginSupport/olivehost.h"
#include "render/ipc/frameslotpool.h"
namespace olive
@@ -53,28 +53,28 @@ RenderProcessor::RenderProcessor(RenderTicketPtr ticket, Renderer *render_ctx,
{
}
TexturePtr RenderProcessor::GenerateTexture(const rational &time,
const rational &frame_length)
TexturePtr RenderProcessor::generate_texture(const Rational &time,
const Rational &frame_length)
{
TimeRange range = TimeRange(time, time + frame_length);
NodeValueTable table;
if (Node *node = QtUtils::ValueToPtr<Node>(ticket_->property("node"))) {
table = GenerateTable(node, range);
if (Node *node = QtUtils::value_to_ptr<Node>(ticket_->property("node"))) {
table = generate_table(node, range);
}
NodeValue tex_val = table.Get(NodeValue::kTexture);
NodeValue tex_val = table.get(NodeValue::k_texture);
ResolveJobs(tex_val);
resolve_jobs(tex_val);
return tex_val.toTexture();
return tex_val.to_texture();
}
FramePtr RenderProcessor::GenerateFrame(TexturePtr texture,
const rational &time)
FramePtr RenderProcessor::generate_frame(TexturePtr texture,
const Rational &time)
{
// Set up output frame parameters
VideoParams frame_params = GetCacheVideoParams();
VideoParams frame_params = get_cache_video_params();
QSize frame_size = ticket_->property("size").value<QSize>();
if (!frame_size.isNull()) {
@@ -84,7 +84,7 @@ FramePtr RenderProcessor::GenerateFrame(TexturePtr texture,
PixelFormat frame_format =
static_cast<PixelFormat::Format>(ticket_->property("format").toInt());
if (frame_format != PixelFormat::INVALID) {
if (frame_format != PixelFormat::invalid) {
frame_params.set_format(frame_format);
}
@@ -94,10 +94,10 @@ FramePtr RenderProcessor::GenerateFrame(TexturePtr texture,
} else {
frame_params.set_channel_count(texture ?
texture->channel_count() :
VideoParams::kRGBAChannelCount);
VideoParams::k_rgba_channel_count);
}
FramePtr frame = Frame::Create();
FramePtr frame = Frame::create();
frame->set_timestamp(time);
frame->set_video_params(frame_params);
frame->allocate();
@@ -112,16 +112,16 @@ FramePtr RenderProcessor::GenerateFrame(TexturePtr texture,
const VideoParams &tex_params = texture->params();
if (output_color_transform) {
TexturePtr transform_tex = render_ctx_->CreateTexture(tex_params);
TexturePtr transform_tex = render_ctx_->create_texture(tex_params);
ColorTransformJob job;
job.SetColorProcessor(output_color_transform);
job.SetInputTexture(texture);
job.SetInputAlphaAssociation(
OLIVE_CONFIG("ReassocLinToNonLin").toBool() ? kAlphaAssociated :
kAlphaNone);
job.set_color_processor(output_color_transform);
job.set_input_texture(texture);
job.set_input_alpha_association(
OAK_CONFIG("ReassocLinToNonLin").toBool() ? k_alpha_associated :
k_alpha_none);
render_ctx_->BlitColorManaged(job, transform_tex.get());
render_ctx_->blit_color_managed(job, transform_tex.get());
texture = transform_tex;
}
@@ -129,26 +129,26 @@ FramePtr RenderProcessor::GenerateFrame(TexturePtr texture,
if (tex_params.effective_width() != frame_params.effective_width() ||
tex_params.effective_height() != frame_params.effective_height() ||
tex_params.format() != frame_params.format()) {
TexturePtr blit_tex = render_ctx_->CreateTexture(frame_params);
TexturePtr blit_tex = render_ctx_->create_texture(frame_params);
QMatrix4x4 matrix = ticket_->property("matrix").value<QMatrix4x4>();
// No color transform, just blit
ShaderJob job;
job.Insert(QStringLiteral("ove_maintex"),
NodeValue(NodeValue::kTexture,
job.insert(QStringLiteral("ove_maintex"),
NodeValue(NodeValue::k_texture,
QVariant::fromValue(texture)));
job.Insert(QStringLiteral("ove_mvpmat"),
NodeValue(NodeValue::kMatrix, matrix));
job.insert(QStringLiteral("ove_mvpmat"),
NodeValue(NodeValue::k_matrix, matrix));
render_ctx_->BlitToTexture(render_ctx_->GetDefaultShader(), job,
render_ctx_->blit_to_texture(render_ctx_->get_default_shader(), job,
blit_tex.get());
// Replace texture that we're going to download in the next step
texture = blit_tex;
}
render_ctx_->DownloadFromTexture(texture->id(), texture->params(),
render_ctx_->download_from_texture(texture->id(), texture->params(),
frame->data(),
frame->linesize_pixels());
if (output_color_transform) {
@@ -163,21 +163,21 @@ FramePtr RenderProcessor::GenerateFrame(TexturePtr texture,
return frame;
}
void RenderProcessor::Run()
void RenderProcessor::run()
{
// Depending on the render ticket type, start a job
RenderManager::TicketType type =
ticket_->property("type").value<RenderManager::TicketType>();
SetCancelPointer(ticket_->GetCancelAtom());
set_cancel_pointer(ticket_->get_cancel_atom());
VideoParams params = ticket_->property("vparam").value<VideoParams>();
params.set_format(PixelFormat::F32);
SetCacheVideoParams(params);
SetCacheAudioParams(ticket_->property("aparam").value<AudioParams>());
params.set_format(PixelFormat::f32);
set_cache_video_params(params);
set_cache_audio_params(ticket_->property("aparam").value<AudioParams>());
if (IsCancelled()) {
ticket_->Finish();
if (is_cancelled()) {
ticket_->finish();
return;
}
@@ -193,40 +193,40 @@ void RenderProcessor::Run()
*/
switch (type) {
case RenderManager::kTypeVideo: {
rational time = ticket_->property("time").value<rational>();
case RenderManager::k_type_video: {
Rational time = ticket_->property("time").value<Rational>();
rational frame_length = GetCacheVideoParams().frame_rate_as_time_base();
if (GetCacheVideoParams().interlacing() !=
VideoParams::kInterlaceNone) {
Rational frame_length = get_cache_video_params().frame_rate_as_time_base();
if (get_cache_video_params().interlacing() !=
VideoParams::k_interlace_none) {
frame_length /= 2;
}
TexturePtr texture = GenerateTexture(time, frame_length);
TexturePtr texture = generate_texture(time, frame_length);
if (!render_ctx_) {
ticket_->Finish();
ticket_->finish();
} else {
if (GetCacheVideoParams().interlacing() !=
VideoParams::kInterlaceNone) {
if (get_cache_video_params().interlacing() !=
VideoParams::k_interlace_none) {
// Get next between frame and interlace it
TexturePtr top = texture;
TexturePtr bottom =
GenerateTexture(time + frame_length, frame_length);
generate_texture(time + frame_length, frame_length);
if (GetCacheVideoParams().interlacing() ==
VideoParams::kInterlacedBottomFirst) {
if (get_cache_video_params().interlacing() ==
VideoParams::k_interlaced_bottom_first) {
std::swap(top, bottom);
}
texture = render_ctx_->InterlaceTexture(top, bottom,
GetCacheVideoParams());
texture = render_ctx_->interlace_texture(top, bottom,
get_cache_video_params());
}
if (HeardCancel()) {
if (heard_cancel()) {
// Finish cancelled ticket with nothing since we can't guarantee the frame we generated
// is actually "complete
ticket_->Finish();
ticket_->finish();
} else {
FramePtr frame;
QString cache = ticket_->property("cache").toString();
@@ -234,85 +234,85 @@ void RenderProcessor::Run()
RenderManager::ReturnType(
ticket_->property("return").toInt());
if (return_type == RenderManager::kFrame || !cache.isEmpty()) {
if (return_type == RenderManager::k_frame || !cache.isEmpty()) {
// Convert to CPU frame
frame = GenerateFrame(texture, time);
frame = generate_frame(texture, time);
// Save to cache if requested
if (!cache.isEmpty()) {
rational timebase =
ticket_->property("cachetimebase").value<rational>();
Rational timebase =
ticket_->property("cachetimebase").value<Rational>();
QUuid uuid =
ticket_->property("cacheid").value<QUuid>();
bool cache_result = FrameHashCache::SaveCacheFrame(
bool cache_result = FrameHashCache::save_cache_frame(
cache, uuid, time, timebase, frame);
ticket_->setProperty("cached", cache_result);
}
}
if (return_type == RenderManager::kTexture) {
if (return_type == RenderManager::k_texture) {
// Return GPU texture
if (!texture) {
texture =
render_ctx_->CreateTexture(GetCacheVideoParams());
render_ctx_->ClearDestination(texture.get());
render_ctx_->create_texture(get_cache_video_params());
render_ctx_->clear_destination(texture.get());
}
render_ctx_->Flush();
ticket_->Finish(QVariant::fromValue(texture));
render_ctx_->flush();
ticket_->finish(QVariant::fromValue(texture));
} else {
ticket_->Finish(QVariant::fromValue(frame));
ticket_->finish(QVariant::fromValue(frame));
}
}
}
break;
}
case RenderManager::kTypeAudio: {
case RenderManager::k_type_audio: {
TimeRange time = ticket_->property("time").value<TimeRange>();
NodeValueTable table;
if (Node *node = QtUtils::ValueToPtr<Node>(ticket_->property("node"))) {
table = GenerateTable(node, time);
if (Node *node = QtUtils::value_to_ptr<Node>(ticket_->property("node"))) {
table = generate_table(node, time);
}
NodeValue sample_val = table.Get(NodeValue::kSamples);
NodeValue sample_val = table.get(NodeValue::k_samples);
ResolveJobs(sample_val);
resolve_jobs(sample_val);
SampleBuffer samples = sample_val.toSamples();
SampleBuffer samples = sample_val.to_samples();
if (samples.is_allocated()) {
if (ticket_->property("clamp").toBool() && !IsCancelled()) {
if (ticket_->property("clamp").toBool() && !is_cancelled()) {
samples.clamp();
}
if (ticket_->property("enablewaveforms").toBool() &&
!IsCancelled()) {
!is_cancelled()) {
AudioVisualWaveform vis;
vis.set_channel_count(samples.audio_params().channel_count());
vis.OverwriteSamples(samples,
vis.overwrite_samples(samples,
samples.audio_params().sample_rate());
ticket_->setProperty("waveform", QVariant::fromValue(vis));
}
}
if (HeardCancel()) {
ticket_->Finish();
if (heard_cancel()) {
ticket_->finish();
} else {
ticket_->Finish(QVariant::fromValue(samples));
ticket_->finish(QVariant::fromValue(samples));
}
break;
}
default:
// Fail
ticket_->Finish();
ticket_->finish();
}
}
DecoderPtr
RenderProcessor::ResolveDecoderFromInput(const QString &decoder_id,
RenderProcessor::resolve_decoder_from_input(const QString &decoder_id,
const Decoder::CodecStream &stream)
{
if (!stream.IsValid()) {
if (!stream.is_valid()) {
qWarning() << "Attempted to resolve the decoder of a null stream";
return nullptr;
}
@@ -336,12 +336,12 @@ RenderProcessor::ResolveDecoderFromInput(const QString &decoder_id,
dec = decoder.decoder;
} else {
// No decoder
decoder.decoder = dec = Decoder::CreateFromID(decoder_id);
decoder.decoder = dec = Decoder::create_from_id(decoder_id);
decoder.last_modified = file_last_modified;
decoder_cache_->insert(stream, decoder);
locker.unlock();
if (!dec->Open(stream)) {
if (!dec->open(stream)) {
qWarning() << "Failed to open decoder for" << stream.filename()
<< "::" << stream.stream();
return nullptr;
@@ -349,35 +349,35 @@ RenderProcessor::ResolveDecoderFromInput(const QString &decoder_id,
if (!render_ctx_) {
// Assume dry run and increment access time
decoder.decoder->IncrementAccessTime(
RenderManager::kDryRunInterval.toDouble() * 1000);
decoder.decoder->increment_access_time(
RenderManager::k_dry_run_interval.to_double() * 1000);
}
}
return dec;
}
NodeValueDatabase RenderProcessor::GenerateDatabase(const Node *node,
NodeValueDatabase RenderProcessor::generate_database(const Node *node,
const TimeRange &range)
{
NodeValueDatabase db = super::GenerateDatabase(node, range);
NodeValueDatabase db = super::generate_database(node, range);
if (const MultiCamNode *multicam =
dynamic_cast<const MultiCamNode *>(node)) {
if (QtUtils::ValueToPtr<MultiCamNode>(ticket_->property("multicam")) ==
if (QtUtils::value_to_ptr<MultiCamNode>(ticket_->property("multicam")) ==
multicam) {
int sz = multicam->GetSourceCount();
int sz = multicam->get_source_count();
QVector<TexturePtr> multicam_tex(sz);
for (int i = 0; i < sz; i++) {
NodeValueTable t =
GenerateTable(multicam->GetConnectedRenderOutput(
multicam->kSourcesInput, i),
generate_table(multicam->get_connected_render_output(
multicam->k_sources_input, i),
range, multicam);
NodeValue val = GenerateRowValueElement(
multicam, multicam->kSourcesInput, i, &t, range);
ResolveJobs(val);
NodeValue val = generate_row_value_element(
multicam, multicam->k_sources_input, i, &t, range);
resolve_jobs(val);
multicam_tex[i] = val.toTexture();
multicam_tex[i] = val.to_texture();
}
ticket_->setProperty("multicam_output",
QVariant::fromValue(multicam_tex));
@@ -387,20 +387,20 @@ NodeValueDatabase RenderProcessor::GenerateDatabase(const Node *node,
return db;
}
void RenderProcessor::Process(RenderTicketPtr ticket, Renderer *render_ctx,
void RenderProcessor::process(RenderTicketPtr ticket, Renderer *render_ctx,
DecoderCache *decoder_cache,
ShaderCache *shader_cache)
{
RenderProcessor p(ticket, render_ctx, decoder_cache, shader_cache);
p.Run();
p.run();
}
void RenderProcessor::ProcessVideoFootage(TexturePtr destination,
void RenderProcessor::process_video_footage(TexturePtr destination,
const FootageJob *stream,
const rational &input_time)
const Rational &input_time)
{
if (ticket_->property("type").value<RenderManager::TicketType>() !=
RenderManager::kTypeVideo) {
RenderManager::k_type_video) {
// Video cannot contribute to audio, so we do nothing here
return;
}
@@ -411,12 +411,12 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination,
VideoParams stream_data = stream->video_params();
ColorManager *color_manager =
QtUtils::ValueToPtr<ColorManager>(ticket_->property("colormanager"));
QtUtils::value_to_ptr<ColorManager>(ticket_->property("colormanager"));
QString using_colorspace = stream_data.colorspace();
if (using_colorspace.isEmpty() && color_manager) {
using_colorspace = color_manager->GetDefaultInputColorSpace();
using_colorspace = color_manager->get_default_input_color_space();
}
if (using_colorspace.isEmpty()) {
@@ -426,37 +426,37 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination,
auto blit_color_managed = [&](const TexturePtr &unmanaged_texture,
const VideoParams &texture_params) {
if (!render_ctx_ || !unmanaged_texture || IsCancelled()) {
if (!render_ctx_ || !unmanaged_texture || is_cancelled()) {
return;
}
// We convert to our rendering pixel format, since that will always be float-based which
// is necessary for correct color conversion
ColorProcessorPtr processor =
ColorProcessor::Create(color_manager, using_colorspace,
color_manager->GetReferenceColorSpace());
ColorProcessor::create(color_manager, using_colorspace,
color_manager->get_reference_color_space());
ColorTransformJob job;
job.SetColorProcessor(processor);
job.SetInputTexture(unmanaged_texture);
job.set_color_processor(processor);
job.set_input_texture(unmanaged_texture);
if (texture_params.channel_count() != VideoParams::kRGBAChannelCount ||
if (texture_params.channel_count() != VideoParams::k_rgba_channel_count ||
texture_params.colorspace() ==
color_manager->GetReferenceColorSpace()) {
job.SetInputAlphaAssociation(kAlphaNone);
color_manager->get_reference_color_space()) {
job.set_input_alpha_association(k_alpha_none);
} else if (texture_params.premultiplied_alpha()) {
job.SetInputAlphaAssociation(kAlphaAssociated);
job.set_input_alpha_association(k_alpha_associated);
} else {
job.SetInputAlphaAssociation(kAlphaUnassociated);
job.set_input_alpha_association(k_alpha_unassociated);
}
render_ctx_->BlitColorManaged(job, destination.get());
render_ctx_->blit_color_managed(job, destination.get());
// macOS TBDR: ensure tile writeback completes before the texture
// is read back in a potentially different shared OpenGL context.
render_ctx_->Flush();
render_ctx_->flush();
};
auto *input_pool = QtUtils::ValueToPtr<ipc::FrameSlotPool>(
auto *input_pool = QtUtils::value_to_ptr<ipc::FrameSlotPool>(
ticket_->property("ipc_input_pool"));
int input_slot = -1;
const QVariantList input_slots =
@@ -481,7 +481,7 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination,
return;
}
const ipc::FrameSlotMeta *meta = input_pool->Meta(uint32_t(input_slot));
const ipc::FrameSlotMeta *meta = input_pool->meta(uint32_t(input_slot));
if (meta && meta->width > 0 && meta->height > 0 &&
meta->data_size > 0 &&
meta->data_size <= int(input_pool->slot_data_bytes())) {
@@ -506,13 +506,13 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination,
using_colorspace = ipc_colorspace;
}
const int bytes_per_pixel = input_params.GetBytesPerPixel();
const int bytes_per_pixel = input_params.get_bytes_per_pixel();
const int linesize_pixels = bytes_per_pixel > 0 ?
meta->linesize / bytes_per_pixel :
input_params.effective_width();
const void *slot_data = input_pool->SlotData(uint32_t(input_slot));
TexturePtr unmanaged_texture = render_ctx_->CreateTexture(
const void *slot_data = input_pool->slot_data(uint32_t(input_slot));
TexturePtr unmanaged_texture = render_ctx_->create_texture(
input_params, slot_data, linesize_pixels);
blit_color_managed(unmanaged_texture, input_params);
@@ -532,7 +532,7 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination,
const bool use_proxy =
static_cast<RenderMode::Mode>(ticket_->property("mode").toInt()) ==
RenderMode::kOffline &&
RenderMode::k_offline &&
stream->has_proxy() && QFileInfo::exists(stream->proxy_filename());
const QString decode_filename = use_proxy ? stream->proxy_filename() :
stream->filename();
@@ -542,30 +542,30 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination,
stream_data.stream_index();
Decoder::CodecStream default_codec_stream(decode_filename, stream_index,
GetCurrentBlock());
get_current_block());
DecoderPtr decoder = nullptr;
switch (stream_data.video_type()) {
case VideoParams::kVideoTypeVideo:
case VideoParams::kVideoTypeStill:
decoder = ResolveDecoderFromInput(decoder_id, default_codec_stream);
case VideoParams::k_video_type_video:
case VideoParams::k_video_type_still:
decoder = resolve_decoder_from_input(decoder_id, default_codec_stream);
break;
case VideoParams::kVideoTypeImageSequence: {
case VideoParams::k_video_type_image_sequence: {
if (render_ctx_) {
// Since image sequences involve multiple files, we don't engage the decoder cache
decoder = Decoder::CreateFromID(decoder_id);
decoder = Decoder::create_from_id(decoder_id);
QString frame_filename;
int64_t frame_number =
stream_data.get_time_in_timebase_units(input_time);
frame_filename = Decoder::TransformImageSequenceFileName(
frame_filename = Decoder::transform_image_sequence_file_name(
decode_filename, frame_number);
// Decoder will close automatically since it's a stream_ptr
decoder->Open(Decoder::CodecStream(frame_filename, stream_index,
GetCurrentBlock()));
decoder->open(Decoder::CodecStream(frame_filename, stream_index,
get_current_block()));
}
break;
}
@@ -576,7 +576,7 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination,
p.divider = stream->video_params().divider();
p.maximum_format = destination->format();
if (!IsCancelled()) {
if (!is_cancelled()) {
VideoParams tex_params = stream->video_params();
if (tex_params.is_valid()) {
@@ -584,16 +584,16 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination,
p.renderer = render_ctx_;
p.time =
(stream_data.video_type() == VideoParams::kVideoTypeVideo) ?
(stream_data.video_type() == VideoParams::k_video_type_video) ?
input_time :
Decoder::kAnyTimecode;
p.cancelled = GetCancelPointer();
Decoder::k_any_timecode;
p.cancelled = get_cancel_pointer();
p.force_range = stream_data.color_range();
p.src_interlacing = stream_data.interlacing();
unmanaged_texture = decoder->RetrieveVideo(p);
unmanaged_texture = decoder->retrieve_video(p);
if (!IsCancelled() && unmanaged_texture) {
if (!is_cancelled() && unmanaged_texture) {
blit_color_managed(unmanaged_texture, stream_data);
}
}
@@ -601,7 +601,7 @@ void RenderProcessor::ProcessVideoFootage(TexturePtr destination,
}
}
void RenderProcessor::ProcessAudioFootage(SampleBuffer &destination,
void RenderProcessor::process_audio_footage(SampleBuffer &destination,
const FootageJob *stream,
const TimeRange &input_time)
{
@@ -615,7 +615,7 @@ void RenderProcessor::ProcessAudioFootage(SampleBuffer &destination,
// audio) for offline renders only, never for export
const bool use_proxy =
static_cast<RenderMode::Mode>(ticket_->property("mode").toInt()) ==
RenderMode::kOffline &&
RenderMode::k_offline &&
stream->has_proxy() && QFileInfo::exists(stream->proxy_filename());
const QString decode_filename = use_proxy ? stream->proxy_filename() :
stream->filename();
@@ -625,25 +625,25 @@ void RenderProcessor::ProcessAudioFootage(SampleBuffer &destination,
stream->proxy_stream_index() :
stream->audio_params().stream_index();
DecoderPtr decoder = ResolveDecoderFromInput(
DecoderPtr decoder = resolve_decoder_from_input(
decoder_id,
Decoder::CodecStream(decode_filename, stream_index, nullptr));
if (decoder) {
const AudioParams &audio_params = GetCacheAudioParams();
const AudioParams &audio_params = get_cache_audio_params();
Decoder::RetrieveAudioStatus status = decoder->RetrieveAudio(
Decoder::RetrieveAudioStatus status = decoder->retrieve_audio(
destination, input_time, audio_params, stream->cache_path(),
loop_mode(),
static_cast<RenderMode::Mode>(ticket_->property("mode").toInt()));
if (status == Decoder::kWaitingForConform) {
if (status == Decoder::k_waiting_for_conform) {
ticket_->setProperty("incomplete", true);
}
}
}
void RenderProcessor::ProcessShader(TexturePtr destination, const Node *node,
void RenderProcessor::process_shader(TexturePtr destination, const Node *node,
const ShaderJob *job)
{
if (!render_ctx_) {
@@ -651,7 +651,7 @@ void RenderProcessor::ProcessShader(TexturePtr destination, const Node *node,
}
QString full_shader_id =
QStringLiteral("%1:%2").arg(node->id(), job->GetShaderID());
QStringLiteral("%1:%2").arg(node->id(), job->get_shader_id());
QMutexLocker locker(shader_cache_->mutex());
@@ -659,8 +659,8 @@ void RenderProcessor::ProcessShader(TexturePtr destination, const Node *node,
if (shader.isNull()) {
// Since we have shader code, compile it now
shader = render_ctx_->CreateNativeShader(
node->GetShaderCode(job->GetShaderID()));
shader = render_ctx_->create_native_shader(
node->get_shader_code(job->get_shader_id()));
if (shader.isNull()) {
// Couldn't find or build the shader required
@@ -673,11 +673,11 @@ void RenderProcessor::ProcessShader(TexturePtr destination, const Node *node,
locker.unlock();
// Run shader
render_ctx_->BlitToTexture(shader, const_cast<ShaderJob &>(*job),
render_ctx_->blit_to_texture(shader, const_cast<ShaderJob &>(*job),
destination.get());
}
void RenderProcessor::ProcessSamples(SampleBuffer &destination,
void RenderProcessor::process_samples(SampleBuffer &destination,
const Node *node, const TimeRange &range,
const SampleJob &job)
{
@@ -687,32 +687,32 @@ void RenderProcessor::ProcessSamples(SampleBuffer &destination,
NodeValueRow value_db;
const AudioParams &audio_params = GetCacheAudioParams();
const AudioParams &audio_params = get_cache_audio_params();
for (size_t i = 0; i < job.samples().sample_count(); i++) {
// Calculate the exact rational time at this sample
// Calculate the exact Rational time at this sample
double sample_to_second =
static_cast<double>(i) /
static_cast<double>(audio_params.sample_rate());
rational this_sample_time =
rational::fromDouble(range.in().toDouble() + sample_to_second);
Rational this_sample_time =
Rational::from_double(range.in().to_double() + sample_to_second);
// Update all non-sample and non-footage inputs
for (auto j = job.GetValues().constBegin();
j != job.GetValues().constEnd(); j++) {
for (auto j = job.get_values().constBegin();
j != job.get_values().constEnd(); j++) {
TimeRange r = TimeRange(this_sample_time, this_sample_time);
NodeValueTable value = ProcessInput(node, j.key(), r);
NodeValueTable value = process_input(node, j.key(), r);
value_db.insert(j.key(),
GenerateRowValue(node, j.key(), &value, r));
generate_row_value(node, j.key(), &value, r));
}
node->ProcessSamples(value_db, job.samples(), destination, i);
node->process_samples(value_db, job.samples(), destination, i);
}
}
void RenderProcessor::ProcessColorTransform(TexturePtr destination,
void RenderProcessor::process_color_transform(TexturePtr destination,
const Node *node,
const ColorTransformJob *job)
{
@@ -720,10 +720,10 @@ void RenderProcessor::ProcessColorTransform(TexturePtr destination,
return;
}
render_ctx_->BlitColorManaged(*job, destination.get());
render_ctx_->blit_color_managed(*job, destination.get());
}
void RenderProcessor::ProcessFrameGeneration(TexturePtr destination,
void RenderProcessor::process_frame_generation(TexturePtr destination,
const Node *node,
const GenerateJob *job)
{
@@ -731,17 +731,17 @@ void RenderProcessor::ProcessFrameGeneration(TexturePtr destination,
return;
}
FramePtr frame = Frame::Create();
FramePtr frame = Frame::create();
frame->set_video_params(destination->params());
frame->allocate();
node->GenerateFrame(frame, *job);
node->generate_frame(frame, *job);
destination->Upload(frame->data(), frame->linesize_pixels());
destination->upload(frame->data(), frame->linesize_pixels());
}
TexturePtr RenderProcessor::ProcessPluginJob(TexturePtr texture,
TexturePtr RenderProcessor::process_plugin_job(TexturePtr texture,
TexturePtr destination,
const Node *node)
{
@@ -761,13 +761,13 @@ TexturePtr RenderProcessor::ProcessPluginJob(TexturePtr texture,
return destination;
}
NodeValueRow &values = plugin_job->GetValues();
NodeValueRow &values = plugin_job->get_values();
auto is_usable_texture = [](const TexturePtr &tex) {
if (!tex) {
return false;
}
if (!tex->IsDummy() && tex->renderer()) {
if (!tex->is_dummy() && tex->renderer()) {
return true;
}
AVFramePtr frame = tex->frame();
@@ -777,10 +777,10 @@ TexturePtr RenderProcessor::ProcessPluginJob(TexturePtr texture,
TexturePtr src = nullptr;
QString effect_input_id;
if (plugin_job->node()) {
effect_input_id = plugin_job->node()->GetEffectInputID();
effect_input_id = plugin_job->node()->get_effect_input_id();
}
if (!effect_input_id.isEmpty()) {
if (TexturePtr effect_tex = values.value(effect_input_id).toTexture();
if (TexturePtr effect_tex = values.value(effect_input_id).to_texture();
is_usable_texture(effect_tex)) {
src = effect_tex;
}
@@ -788,19 +788,19 @@ TexturePtr RenderProcessor::ProcessPluginJob(TexturePtr texture,
if (!src) {
const QString source_key =
QString::fromUtf8(kOfxImageEffectSimpleSourceClipName);
if (TexturePtr source_tex = values.value(source_key).toTexture();
if (TexturePtr source_tex = values.value(source_key).to_texture();
is_usable_texture(source_tex)) {
src = source_tex;
} else if (TexturePtr effect_tex =
values.value(plugin::kTextureInput).toTexture();
values.value(plugin::k_texture_input).to_texture();
is_usable_texture(effect_tex)) {
src = effect_tex;
}
}
if (!src) {
for (auto it = values.cbegin(); it != values.cend(); ++it) {
if (it.value().type() == NodeValue::kTexture) {
if (TexturePtr any_tex = it.value().toTexture();
if (it.value().type() == NodeValue::k_texture) {
if (TexturePtr any_tex = it.value().to_texture();
is_usable_texture(any_tex)) {
src = any_tex;
break;
@@ -809,15 +809,15 @@ TexturePtr RenderProcessor::ProcessPluginJob(TexturePtr texture,
}
}
plugin_renderer.RenderPlugin(src, *plugin_job, destination,
plugin_renderer.render_plugin(src, *plugin_job, destination,
destination->params(), true, false);
return destination;
}
TexturePtr RenderProcessor::ProcessVideoCacheJob(const CacheJob *val)
TexturePtr RenderProcessor::process_video_cache_job(const CacheJob *val)
{
FramePtr frame = FrameHashCache::LoadCacheFrame(val->GetFilename());
FramePtr frame = FrameHashCache::load_cache_frame(val->get_filename());
if (frame) {
// Auto-detect and discard black/empty cached frames (macOS TBDR artifact)
bool all_black = true;
@@ -835,37 +835,37 @@ TexturePtr RenderProcessor::ProcessVideoCacheJob(const CacheJob *val)
}
if (all_black) {
qWarning() << "[CACHE] Discarding black cached frame:"
<< val->GetFilename()
<< "time=" << frame->timestamp().toDouble()
<< val->get_filename()
<< "time=" << frame->timestamp().to_double()
<< "size=" << frame->allocated_size();
QFile::remove(val->GetFilename());
QFile::remove(val->get_filename());
return nullptr;
}
TexturePtr tex = CreateTexture(frame->video_params());
TexturePtr tex = create_texture(frame->video_params());
if (tex) {
tex->Upload(frame->data(), frame->linesize_pixels());
tex->upload(frame->data(), frame->linesize_pixels());
return tex;
}
} else {
QStringList s = ticket_->property("badcache").toStringList();
s.append(val->GetFilename());
s.append(val->get_filename());
ticket_->setProperty("badcache", s);
}
return nullptr;
}
TexturePtr RenderProcessor::CreateTexture(const VideoParams &p)
TexturePtr RenderProcessor::create_texture(const VideoParams &p)
{
if (render_ctx_) {
return render_ctx_->CreateTexture(p);
return render_ctx_->create_texture(p);
} else {
return super::CreateTexture(p);
return super::create_texture(p);
}
}
void RenderProcessor::ConvertToReferenceSpace(TexturePtr destination,
void RenderProcessor::convert_to_reference_space(TexturePtr destination,
TexturePtr source,
const QString &input_cs)
{
@@ -874,23 +874,23 @@ void RenderProcessor::ConvertToReferenceSpace(TexturePtr destination,
}
ColorManager *color_manager =
QtUtils::ValueToPtr<ColorManager>(ticket_->property("colormanager"));
ColorProcessorPtr cp = ColorProcessor::Create(
color_manager, input_cs, color_manager->GetReferenceColorSpace());
QtUtils::value_to_ptr<ColorManager>(ticket_->property("colormanager"));
ColorProcessorPtr cp = ColorProcessor::create(
color_manager, input_cs, color_manager->get_reference_color_space());
ColorTransformJob ctj;
ctj.SetColorProcessor(cp);
ctj.SetInputTexture(source);
ctj.SetInputAlphaAssociation(kAlphaAssociated);
ctj.set_color_processor(cp);
ctj.set_input_texture(source);
ctj.set_input_alpha_association(k_alpha_associated);
render_ctx_->BlitColorManaged(ctj, destination.get());
render_ctx_->blit_color_managed(ctj, destination.get());
}
bool RenderProcessor::UseCache() const
bool RenderProcessor::use_cache() const
{
return static_cast<RenderMode::Mode>(ticket_->property("mode").toInt()) ==
RenderMode::kOffline;
RenderMode::k_offline;
}
}
+23 -23
View File
@@ -19,8 +19,8 @@
***/
#ifndef RENDERPROCESSOR_H
#define RENDERPROCESSOR_H
#ifndef OAK_RENDERPROCESSOR_H
#define OAK_RENDERPROCESSOR_H
#include "node/block/clip/clip.h"
#include <memory>
@@ -39,10 +39,10 @@ class PluginRenderer;
class RenderProcessor : public NodeTraverser {
public:
virtual NodeValueDatabase GenerateDatabase(const Node *node,
virtual NodeValueDatabase generate_database(const Node *node,
const TimeRange &range) override;
static void Process(RenderTicketPtr ticket, Renderer *render_ctx,
static void process(RenderTicketPtr ticket, Renderer *render_ctx,
DecoderCache *decoder_cache, ShaderCache *shader_cache);
struct RenderedWaveform {
@@ -53,60 +53,60 @@ public:
};
protected:
virtual void ProcessVideoFootage(TexturePtr destination,
virtual void process_video_footage(TexturePtr destination,
const FootageJob *stream,
const rational &input_time) override;
const Rational &input_time) override;
virtual void ProcessAudioFootage(SampleBuffer &destination,
virtual void process_audio_footage(SampleBuffer &destination,
const FootageJob *stream,
const TimeRange &input_time) override;
virtual void ProcessShader(TexturePtr destination, const Node *node,
virtual void process_shader(TexturePtr destination, const Node *node,
const ShaderJob *job) override;
virtual void ProcessSamples(SampleBuffer &destination, const Node *node,
virtual void process_samples(SampleBuffer &destination, const Node *node,
const TimeRange &range,
const SampleJob &job) override;
virtual void ProcessColorTransform(TexturePtr destination, const Node *node,
virtual void process_color_transform(TexturePtr destination, const Node *node,
const ColorTransformJob *job) override;
virtual void ProcessFrameGeneration(TexturePtr destination,
virtual void process_frame_generation(TexturePtr destination,
const Node *node,
const GenerateJob *job) override;
virtual TexturePtr ProcessPluginJob(TexturePtr texture,
virtual TexturePtr process_plugin_job(TexturePtr texture,
TexturePtr destination,
const Node *node) override;
virtual TexturePtr ProcessVideoCacheJob(const CacheJob *val) override;
virtual TexturePtr process_video_cache_job(const CacheJob *val) override;
virtual TexturePtr CreateTexture(const VideoParams &p) override;
virtual TexturePtr create_texture(const VideoParams &p) override;
virtual SampleBuffer CreateSampleBuffer(const AudioParams &params,
virtual SampleBuffer create_sample_buffer(const AudioParams &params,
int sample_count) override
{
return SampleBuffer(params, sample_count);
}
virtual void ConvertToReferenceSpace(TexturePtr destination,
virtual void convert_to_reference_space(TexturePtr destination,
TexturePtr source,
const QString &input_cs) override;
virtual bool UseCache() const override;
virtual bool use_cache() const override;
private:
RenderProcessor(RenderTicketPtr ticket, Renderer *render_ctx,
DecoderCache *decoder_cache, ShaderCache *shader_cache);
TexturePtr GenerateTexture(const rational &time,
const rational &frame_length);
TexturePtr generate_texture(const Rational &time,
const Rational &frame_length);
FramePtr GenerateFrame(TexturePtr texture, const rational &time);
FramePtr generate_frame(TexturePtr texture, const Rational &time);
void Run();
void run();
DecoderPtr ResolveDecoderFromInput(const QString &decoder_id,
DecoderPtr resolve_decoder_from_input(const QString &decoder_id,
const Decoder::CodecStream &stream);
RenderTicketPtr ticket_;
@@ -124,4 +124,4 @@ private:
Q_DECLARE_METATYPE(olive::RenderProcessor::RenderedWaveform)
#endif // RENDERPROCESSOR_H
#endif // OAK_RENDERPROCESSOR_H
+32 -32
View File
@@ -31,14 +31,14 @@ RenderTicket::RenderTicket()
{
}
void RenderTicket::WaitForFinished(QMutex *mutex)
void RenderTicket::wait_for_finished(QMutex *mutex)
{
if (is_running_) {
wait_.wait(mutex);
}
}
void RenderTicket::Start()
void RenderTicket::start()
{
QMutexLocker locker(&lock_);
@@ -47,33 +47,33 @@ void RenderTicket::Start()
result_.clear();
}
void RenderTicket::Finish()
void RenderTicket::finish()
{
FinishInternal(false, QVariant());
finish_internal(false, QVariant());
}
void RenderTicket::Finish(QVariant result)
void RenderTicket::finish(QVariant result)
{
FinishInternal(true, result);
finish_internal(true, result);
}
QVariant RenderTicket::Get()
QVariant RenderTicket::get()
{
WaitForFinished();
wait_for_finished();
// We don't have to mutex around this because there is no way to write to `result_` after
// the ticket has finished and the above function blocks the calling thread until it is finished
return result_;
}
void RenderTicket::WaitForFinished()
void RenderTicket::wait_for_finished()
{
QMutexLocker locker(&lock_);
WaitForFinished(&lock_);
wait_for_finished(&lock_);
}
bool RenderTicket::IsRunning(bool lock)
bool RenderTicket::is_running(bool lock)
{
if (lock) {
lock_.lock();
@@ -88,7 +88,7 @@ bool RenderTicket::IsRunning(bool lock)
return running;
}
int RenderTicket::GetFinishCount(bool lock)
int RenderTicket::get_finish_count(bool lock)
{
if (lock) {
lock_.lock();
@@ -103,14 +103,14 @@ int RenderTicket::GetFinishCount(bool lock)
return count;
}
bool RenderTicket::HasResult()
bool RenderTicket::has_result()
{
QMutexLocker locker(&lock_);
return has_result_;
}
void RenderTicket::FinishInternal(bool has_result, QVariant result)
void RenderTicket::finish_internal(bool has_result, QVariant result)
{
QMutexLocker locker(&lock_);
@@ -126,7 +126,7 @@ void RenderTicket::FinishInternal(bool has_result, QVariant result)
locker.unlock();
emit Finished();
emit finished();
}
}
@@ -136,7 +136,7 @@ RenderTicketWatcher::RenderTicketWatcher(QObject *parent)
{
}
void RenderTicketWatcher::SetTicket(RenderTicketPtr ticket)
void RenderTicketWatcher::set_ticket(RenderTicketPtr ticket)
{
if (ticket_) {
qCritical() << "Tried to set a ticket on a RenderTicketWatcher twice";
@@ -153,62 +153,62 @@ void RenderTicketWatcher::SetTicket(RenderTicketPtr ticket)
// Lock ticket so we can query if it's already finished by the time this code runs
QMutexLocker locker(ticket->lock());
connect(ticket_.get(), &RenderTicket::Finished, this,
&RenderTicketWatcher::TicketFinished);
connect(ticket_.get(), &RenderTicket::finished, this,
&RenderTicketWatcher::ticket_finished);
if (!ticket_->IsRunning(false) && ticket_->GetFinishCount(false) > 0) {
if (!ticket_->is_running(false) && ticket_->get_finish_count(false) > 0) {
// Ticket has already finished before, so we emit a signal asynchronously
// to avoid deleting this watcher before the caller has a chance to use
// the returned pointer.
QMetaObject::invokeMethod(this, &RenderTicketWatcher::TicketFinished,
QMetaObject::invokeMethod(this, &RenderTicketWatcher::ticket_finished,
Qt::QueuedConnection);
}
}
bool RenderTicketWatcher::IsRunning()
bool RenderTicketWatcher::is_running()
{
if (ticket_) {
return ticket_->IsRunning();
return ticket_->is_running();
} else {
return false;
}
}
void RenderTicketWatcher::WaitForFinished()
void RenderTicketWatcher::wait_for_finished()
{
if (ticket_) {
ticket_->WaitForFinished();
ticket_->wait_for_finished();
}
}
QVariant RenderTicketWatcher::Get()
QVariant RenderTicketWatcher::get()
{
if (ticket_) {
return ticket_->Get();
return ticket_->get();
} else {
return QVariant();
}
}
bool RenderTicketWatcher::HasResult()
bool RenderTicketWatcher::has_result()
{
if (ticket_) {
return ticket_->HasResult();
return ticket_->has_result();
} else {
return false;
}
}
void RenderTicketWatcher::Cancel()
void RenderTicketWatcher::cancel()
{
if (ticket_) {
ticket_->Cancel();
ticket_->cancel();
}
}
void RenderTicketWatcher::TicketFinished()
void RenderTicketWatcher::ticket_finished()
{
emit Finished(this);
emit finished(this);
}
}
+23 -23
View File
@@ -19,8 +19,8 @@
***/
#ifndef RENDERTICKET_H
#define RENDERTICKET_H
#ifndef OAK_RENDERTICKET_H
#define OAK_RENDERTICKET_H
#include <QDateTime>
#include <QMutex>
@@ -44,7 +44,7 @@ public:
* This function is thread safe, unless `lock` is set to false. Then the caller has responsibility
* of locking the mutex before and unlocking after this function is called.
*/
bool IsRunning(bool lock = true);
bool is_running(bool lock = true);
/**
* @brief Determine how many times ticket has been finished
@@ -52,27 +52,27 @@ public:
* This function is thread safe, unless `lock` is set to false. Then the caller has responsibility
* of locking the mutex before and unlocking after this function is called.
*/
int GetFinishCount(bool lock = true);
int get_finish_count(bool lock = true);
/**
* @brief Check if this ticket has a result
*
* If this ticket is running, this will always return false.
*/
bool HasResult();
bool has_result();
/**
* @brief Get value, if any
*/
QVariant Get();
QVariant get();
/**
* @brief Wait for ticket to be finished
*
* If this ticket is not running, this function returns immediately.
*/
void WaitForFinished();
void WaitForFinished(QMutex *mutex);
void wait_for_finished();
void wait_for_finished(QMutex *mutex);
/**
* @brief Access this ticket's mutex
@@ -90,30 +90,30 @@ public:
*
* If any value is set, it is cleared.
*/
void Start();
void start();
/**
* @brief Finish ticket with no value
*
* Sets ticket to no longer running and assume it has received no result.
*/
void Finish();
void finish();
/**
* @brief Finish ticket with value
*
* Sets ticket to no longer running and provide a value generated by the operation requested.
*/
void Finish(QVariant result);
void finish(QVariant result);
signals:
/**
* @brief Emitted when finish has been called by any means (either cancelled or with a result)
*/
void Finished();
void finished();
private:
void FinishInternal(bool has_result, QVariant result);
void finish_internal(bool has_result, QVariant result);
bool is_running_;
@@ -135,35 +135,35 @@ class RenderTicketWatcher : public QObject {
public:
RenderTicketWatcher(QObject *parent = nullptr);
RenderTicketPtr GetTicket() const
RenderTicketPtr get_ticket() const
{
return ticket_;
}
void SetTicket(RenderTicketPtr ticket);
void set_ticket(RenderTicketPtr ticket);
bool IsRunning();
bool is_running();
void WaitForFinished();
void wait_for_finished();
QVariant Get();
QVariant get();
bool HasResult();
bool has_result();
void Cancel();
void cancel();
signals:
void Finished(RenderTicketWatcher *watcher);
void finished(RenderTicketWatcher *watcher);
private:
RenderTicketPtr ticket_;
private slots:
void TicketFinished();
void ticket_finished();
};
}
Q_DECLARE_METATYPE(olive::RenderTicketPtr)
#endif // RENDERTICKET_H
#endif // OAK_RENDERTICKET_H
File diff suppressed because it is too large Load Diff
+39 -39
View File
@@ -18,8 +18,8 @@
***/
#ifndef RENDERWORKERPOOL_H
#define RENDERWORKERPOOL_H
#ifndef OAK_RENDERWORKERPOOL_H
#define OAK_RENDERWORKERPOOL_H
#include <QHash>
#include <QMutex>
@@ -52,12 +52,12 @@ public:
QObject *parent = nullptr);
~RenderWorkerPool() override;
bool SubmitFrame(RenderTicketPtr ticket,
bool submit_frame(RenderTicketPtr ticket,
const RenderManager::RenderVideoParams &params);
bool RemoveTicket(RenderTicketPtr ticket);
bool remove_ticket(RenderTicketPtr ticket);
void Shutdown();
void shutdown();
protected:
void run() override;
@@ -78,10 +78,10 @@ private:
};
enum class JobResult {
kFinished,
kRetryableFailure,
kFatalFailure,
kCancelled
k_finished,
k_retryable_failure,
k_fatal_failure,
k_cancelled
};
struct ActiveJob {
@@ -113,41 +113,41 @@ private:
QString path;
};
bool PrepareJob(RenderTicketPtr ticket,
bool prepare_job(RenderTicketPtr ticket,
const RenderManager::RenderVideoParams &params, Job *job);
bool WriteGraphSnapshot(Project *project, QString *path);
bool IsSupported(const RenderManager::RenderVideoParams &params) const;
bool write_graph_snapshot(Project *project, QString *path);
bool is_supported(const RenderManager::RenderVideoParams &params) const;
void WorkerLoop(int worker_index,
void worker_loop(int worker_index,
std::vector<std::unique_ptr<PooledWorker>> *local_pool);
void ProcessJob(const Job &job, int worker_index,
void process_job(const Job &job, int worker_index,
std::vector<std::unique_ptr<PooledWorker>> *local_pool);
JobResult ProcessJobAttempt(const Job &job, int worker_index,
JobResult process_job_attempt(const Job &job, int worker_index,
int attempt_index, PooledWorker *worker);
void FinishWithFrame(RenderTicketPtr ticket, const ipc::FrameSlotPool &pool,
void finish_with_frame(RenderTicketPtr ticket, const ipc::FrameSlotPool &pool,
uint32_t slot);
void CleanupGraphFile(const QString &path);
void AddGraphPathRef(const QString &path);
void AddGraphPathRefLocked(const QString &path);
void ReleaseGraphPathRef(const QString &path);
void ReleaseGraphPathRefLocked(const QString &path);
void SetGraphPathCached(const QString &path, bool cached);
void SetGraphPathCachedLocked(const QString &path, bool cached);
void CancelActiveProcess(qint64 process_id);
void SetActiveWorker(int worker_index, RenderTicketPtr ticket,
void cleanup_graph_file(const QString &path);
void add_graph_path_ref(const QString &path);
void add_graph_path_ref_locked(const QString &path);
void release_graph_path_ref(const QString &path);
void release_graph_path_ref_locked(const QString &path);
void set_graph_path_cached(const QString &path, bool cached);
void set_graph_path_cached_locked(const QString &path, bool cached);
void cancel_active_process(qint64 process_id);
void set_active_worker(int worker_index, RenderTicketPtr ticket,
QProcess *worker, qint64 ticket_id);
void ClearActiveWorker(int worker_index, qint64 process_id);
int WorkerCount() const;
void clear_active_worker(int worker_index, qint64 process_id);
int worker_count() const;
std::unique_ptr<PooledWorker>
AcquireWorker(std::vector<std::unique_ptr<PooledWorker>> *local_pool,
acquire_worker(std::vector<std::unique_ptr<PooledWorker>> *local_pool,
const QString &graph_path);
void ReturnWorker(std::vector<std::unique_ptr<PooledWorker>> *local_pool,
void return_worker(std::vector<std::unique_ptr<PooledWorker>> *local_pool,
std::unique_ptr<PooledWorker> worker, bool keep_alive);
void ShutdownWorker(PooledWorker *worker);
void shutdown_worker(PooledWorker *worker);
void
ShutdownLocalPool(std::vector<std::unique_ptr<PooledWorker>> *local_pool);
void ClearGraphCache();
shutdown_local_pool(std::vector<std::unique_ptr<PooledWorker>> *local_pool);
void clear_graph_cache();
DecoderCache *decoder_cache_;
QString gpu_backend_;
@@ -160,14 +160,14 @@ private:
QHash<QString, int> graph_path_ref_count_;
QSet<QString> cached_graph_paths_;
static constexpr uint32_t kOutputSlots = 2;
static constexpr int kMaxAttempts = 2;
static constexpr int kMaxWidth = 4096;
static constexpr int kMaxHeight = 2160;
static constexpr int kWorkerIdleTimeoutMs = 30000;
static constexpr int kWorkerMaxUses = 100;
static constexpr uint32_t k_output_slots = 2;
static constexpr int k_max_attempts = 2;
static constexpr int k_max_width = 4096;
static constexpr int k_max_height = 2160;
static constexpr int k_worker_idle_timeout_ms = 30000;
static constexpr int k_worker_max_uses = 100;
};
}
#endif // RENDERWORKERPOOL_H
#endif // OAK_RENDERWORKERPOOL_H
+3 -3
View File
@@ -19,8 +19,8 @@
***/
#ifndef SHADERCODE_H
#define SHADERCODE_H
#ifndef OAK_SHADERCODE_H
#define OAK_SHADERCODE_H
#include "common/filefunctions.h"
@@ -62,4 +62,4 @@ private:
}
#endif // SHADERCODE_H
#endif // OAK_SHADERCODE_H
+35 -35
View File
@@ -28,24 +28,24 @@
namespace olive
{
QString SubtitleParams::GenerateASSHeader()
QString SubtitleParams::generate_ass_header()
{
// NOTE: We'll probably implement more customization as we support ASS better. Right now, we only
// natively support SRT and only make this header because FFmpeg requires it.
static const int kAssDefaultPlayResX = 384;
static const int kAssDefaultPlayResY = 288;
static const QString kAssDefaultFont = QStringLiteral("Arial");
static const int kAssDefaultFontSize = 16;
static const int kAssDefaultPrimaryColor = 0xFFFFFF; // White
static const int kAssDefaultSecondaryColor = 0xFFFFFF; // White
static const int kAssDefaultOutlineColor = 0x000000; // Black
static const int kAssDefaultBackColor = 0x000000; // Black
static const int kAssBold = 0;
static const int kAssItalic = 0;
static const int kAssUnderline = 0;
static const int kAssStrike = 0;
static const int kAssBorderStyle = 1;
static const int kAssAlignment = 2;
static const int k_ass_default_play_res_x = 384;
static const int k_ass_default_play_res_y = 288;
static const QString k_ass_default_font = QStringLiteral("Arial");
static const int k_ass_default_font_size = 16;
static const int k_ass_default_primary_color = 0xFFFFFF; // White
static const int k_ass_default_secondary_color = 0xFFFFFF; // White
static const int k_ass_default_outline_color = 0x000000; // Black
static const int k_ass_default_back_color = 0x000000; // Black
static const int k_ass_bold = 0;
static const int k_ass_italic = 0;
static const int k_ass_underline = 0;
static const int k_ass_strike = 0;
static const int k_ass_border_style = 1;
static const int k_ass_alignment = 2;
QString ass_code;
@@ -56,9 +56,9 @@ QString SubtitleParams::GenerateASSHeader()
QCoreApplication::applicationVersion()));
ass_code.append(QStringLiteral("ScriptType: v4.00+\r\n"));
ass_code.append(QStringLiteral("PlayResX: %1\r\n")
.arg(QString::number(kAssDefaultPlayResX)));
.arg(QString::number(k_ass_default_play_res_x)));
ass_code.append(QStringLiteral("PlayResY: %1\r\n")
.arg(QString::number(kAssDefaultPlayResY)));
.arg(QString::number(k_ass_default_play_res_y)));
ass_code.append(QStringLiteral("ScaledBorderAndShadow: yes\r\n"));
ass_code.append(QStringLiteral("\r\n"));
@@ -81,20 +81,20 @@ QString SubtitleParams::GenerateASSHeader()
// Font{name,size}
ass_code.append(QStringLiteral("%1,%2,").arg(
kAssDefaultFont, QString::number(kAssDefaultFontSize)));
k_ass_default_font, QString::number(k_ass_default_font_size)));
// {Primary,Secondary,Outline,Back}Colour
ass_code.append(QStringLiteral("&H%1,&H%2,&H%3,&H%4,")
.arg(QString::number(kAssDefaultPrimaryColor, 16),
QString::number(kAssDefaultSecondaryColor, 16),
QString::number(kAssDefaultOutlineColor, 16),
QString::number(kAssDefaultBackColor, 16)));
.arg(QString::number(k_ass_default_primary_color, 16),
QString::number(k_ass_default_secondary_color, 16),
QString::number(k_ass_default_outline_color, 16),
QString::number(k_ass_default_back_color, 16)));
// Bold, Italic, Underline, StrikeOut
ass_code.append(
QStringLiteral("%1,%2,%3,%4,")
.arg(QString::number(kAssBold), QString::number(kAssItalic),
QString::number(kAssUnderline), QString::number(kAssStrike)));
.arg(QString::number(k_ass_bold), QString::number(k_ass_italic),
QString::number(k_ass_underline), QString::number(k_ass_strike)));
// Scale{X,Y}
ass_code.append(QStringLiteral("100,100,"));
@@ -104,11 +104,11 @@ QString SubtitleParams::GenerateASSHeader()
// BorderStyle, Outline, Shadow
ass_code.append(
QStringLiteral("%1,1,0,").arg(QString::number(kAssBorderStyle)));
QStringLiteral("%1,1,0,").arg(QString::number(k_ass_border_style)));
// Alignment, Margin[LRV]
ass_code.append(
QStringLiteral("%1,10,10,10,").arg(QString::number(kAssAlignment)));
QStringLiteral("%1,10,10,10,").arg(QString::number(k_ass_alignment)));
// Encoding
ass_code.append(QStringLiteral("0\r\n"));
@@ -120,28 +120,28 @@ QString SubtitleParams::GenerateASSHeader()
return ass_code;
}
void SubtitleParams::Load(QXmlStreamReader *reader)
void SubtitleParams::load(QXmlStreamReader *reader)
{
this->clear();
while (XMLReadNextStartElement(reader)) {
while (xml_read_next_start_element(reader)) {
if (reader->name() == QStringLiteral("streamindex")) {
set_stream_index(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("enabled")) {
set_enabled(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("subtitles")) {
while (XMLReadNextStartElement(reader)) {
while (xml_read_next_start_element(reader)) {
if (reader->name() == QStringLiteral("subtitle")) {
rational in, out;
Rational in, out;
QString text;
XMLAttributeLoop(reader, attr)
{
if (attr.name() == QStringLiteral("in")) {
in = rational::fromString(
in = Rational::from_string(
attr.value().toString().toStdString());
} else if (attr.name() == QStringLiteral("out")) {
out = rational::fromString(
out = Rational::from_string(
attr.value().toString().toStdString());
}
}
@@ -159,7 +159,7 @@ void SubtitleParams::Load(QXmlStreamReader *reader)
}
}
void SubtitleParams::Save(QXmlStreamWriter *writer) const
void SubtitleParams::save(QXmlStreamWriter *writer) const
{
writer->writeTextElement(QStringLiteral("streamindex"),
QString::number(stream_index_));
@@ -171,10 +171,10 @@ void SubtitleParams::Save(QXmlStreamWriter *writer) const
writer->writeStartElement(QStringLiteral("subtitle"));
writer->writeAttribute(
QStringLiteral("in"),
QString::fromStdString(it->time().in().toString()));
QString::fromStdString(it->time().in().to_string()));
writer->writeAttribute(
QStringLiteral("out"),
QString::fromStdString(it->time().out().toString()));
QString::fromStdString(it->time().out().to_string()));
writer->writeCharacters(it->text());
writer->writeEndElement(); // subtitle
}
+7 -7
View File
@@ -19,8 +19,8 @@
***/
#ifndef SUBTITLEPARAMS_H
#define SUBTITLEPARAMS_H
#ifndef OAK_SUBTITLEPARAMS_H
#define OAK_SUBTITLEPARAMS_H
#include <olive/core/core.h>
#include <QRect>
@@ -75,18 +75,18 @@ public:
enabled_ = true;
}
static QString GenerateASSHeader();
static QString generate_ass_header();
void Load(QXmlStreamReader *reader);
void load(QXmlStreamReader *reader);
void Save(QXmlStreamWriter *writer) const;
void save(QXmlStreamWriter *writer) const;
bool is_valid() const
{
return !this->empty();
}
rational duration() const
Rational duration() const
{
if (this->empty()) {
return 0;
@@ -124,4 +124,4 @@ private:
Q_DECLARE_METATYPE(olive::Subtitle)
Q_DECLARE_METATYPE(olive::SubtitleParams)
#endif // SUBTITLEPARAMS_H
#endif // OAK_SUBTITLEPARAMS_H
+10 -10
View File
@@ -27,13 +27,13 @@
namespace olive
{
const Texture::Interpolation Texture::kDefaultInterpolation =
Texture::kMipmappedLinear;
const Texture::Interpolation Texture::k_default_interpolation =
Texture::k_mipmapped_linear;
Texture::~Texture()
{
if (IsRendererAlive()) {
renderer_->DestroyTexture(this);
if (is_renderer_alive()) {
renderer_->destroy_texture(this);
}
if (job_) {
@@ -41,17 +41,17 @@ Texture::~Texture()
}
}
void Texture::Upload(void *data, int linesize)
void Texture::upload(void *data, int linesize)
{
if (IsRendererAlive()) {
renderer_->UploadToTexture(this->id(), this->params(), data, linesize);
if (is_renderer_alive()) {
renderer_->upload_to_texture(this->id(), this->params(), data, linesize);
}
}
void Texture::Download(void *data, int linesize)
void Texture::download(void *data, int linesize)
{
if (IsRendererAlive()) {
renderer_->DownloadFromTexture(this->id(), this->params(), data,
if (is_renderer_alive()) {
renderer_->download_from_texture(this->id(), this->params(), data,
linesize);
}
}
+15 -15
View File
@@ -19,8 +19,8 @@
***/
#ifndef RENDERTEXTURE_H
#define RENDERTEXTURE_H
#ifndef OAK_RENDERTEXTURE_H
#define OAK_RENDERTEXTURE_H
#include "common/avframeptr.h"
@@ -44,9 +44,9 @@ using TexturePtr = std::shared_ptr<Texture>;
class Texture {
public:
enum Interpolation { kNearest, kLinear, kMipmappedLinear };
enum Interpolation { k_nearest, k_linear, k_mipmapped_linear };
static const Interpolation kDefaultInterpolation;
static const Interpolation k_default_interpolation;
/**
* @brief Construct a dummy texture with no renderer backend
@@ -93,21 +93,21 @@ public:
}
template <typename T>
static TexturePtr Job(const VideoParams &p, const T &j)
static TexturePtr job(const VideoParams &p, const T &j)
{
return std::make_shared<Texture>(p, j);
}
template <typename T> TexturePtr toJob(const T &job)
template <typename T> TexturePtr to_job(const T &job)
{
return Texture::Job(params_, job);
return Texture::job(params_, job);
}
void Upload(void *data, int linesize);
void upload(void *data, int linesize);
void Download(void *data, int linesize);
void download(void *data, int linesize);
bool IsDummy() const
bool is_dummy() const
{
return !renderer_;
}
@@ -142,7 +142,7 @@ public:
return params_.divider();
}
const rational &pixel_aspect_ratio() const
const Rational &pixel_aspect_ratio() const
{
return params_.pixel_aspect_ratio();
}
@@ -152,7 +152,7 @@ public:
return renderer_;
}
bool IsJob() const
bool is_job() const
{
return job_;
}
@@ -160,7 +160,7 @@ public:
{
return job_;
}
void handleFrame(AVFramePtr ptr)
void handle_frame(AVFramePtr ptr)
{
frame_ = ptr;
}
@@ -170,7 +170,7 @@ public:
}
private:
bool IsRendererAlive() const
bool is_renderer_alive() const
{
return renderer_ &&
(!renderer_lifetime_ || renderer_lifetime_->alive.load());
@@ -192,4 +192,4 @@ private:
Q_DECLARE_METATYPE(olive::TexturePtr)
#endif // RENDERTEXTURE_H
#endif // OAK_RENDERTEXTURE_H
+97 -97
View File
@@ -32,41 +32,41 @@
namespace olive
{
const int VideoParams::kInternalChannelCount = kRGBAChannelCount;
const int VideoParams::k_internal_channel_count = k_rgba_channel_count;
const rational VideoParams::kPixelAspectSquare(1);
const rational VideoParams::kPixelAspectNTSCStandard(8, 9);
const rational VideoParams::kPixelAspectNTSCWidescreen(32, 27);
const rational VideoParams::kPixelAspectPALStandard(16, 15);
const rational VideoParams::kPixelAspectPALWidescreen(64, 45);
const rational VideoParams::kPixelAspect1080Anamorphic(4, 3);
const Rational VideoParams::k_pixel_aspect_square(1);
const Rational VideoParams::k_pixel_aspect_ntsc_standard(8, 9);
const Rational VideoParams::k_pixel_aspect_ntsc_widescreen(32, 27);
const Rational VideoParams::k_pixel_aspect_pal_standard(16, 15);
const Rational VideoParams::k_pixel_aspect_pal_widescreen(64, 45);
const Rational VideoParams::k_pixel_aspect1080_anamorphic(4, 3);
const QVector<rational> VideoParams::kSupportedFrameRates = {
rational(10, 1), // 10 FPS
rational(15, 1), // 15 FPS
rational(24000, 1001), // 23.976 FPS
rational(24, 1), // 24 FPS
rational(25, 1), // 25 FPS
rational(30000, 1001), // 29.97 FPS
rational(30, 1), // 30 FPS
rational(48000, 1001), // 47.952 FPS
rational(48, 1), // 48 FPS
rational(50, 1), // 50 FPS
rational(60000, 1001), // 59.94 FPS
rational(60, 1) // 60 FPS
const QVector<Rational> VideoParams::k_supported_frame_rates = {
Rational(10, 1), // 10 FPS
Rational(15, 1), // 15 FPS
Rational(24000, 1001), // 23.976 FPS
Rational(24, 1), // 24 FPS
Rational(25, 1), // 25 FPS
Rational(30000, 1001), // 29.97 FPS
Rational(30, 1), // 30 FPS
Rational(48000, 1001), // 47.952 FPS
Rational(48, 1), // 48 FPS
Rational(50, 1), // 50 FPS
Rational(60000, 1001), // 59.94 FPS
Rational(60, 1) // 60 FPS
};
const QVector<int> VideoParams::kSupportedDividers = {
const QVector<int> VideoParams::k_supported_dividers = {
1, 2, 3, 4, 6, 8, 12, 16
};
const QVector<rational> VideoParams::kStandardPixelAspects = {
VideoParams::kPixelAspectSquare,
VideoParams::kPixelAspectNTSCStandard,
VideoParams::kPixelAspectNTSCWidescreen,
VideoParams::kPixelAspectPALStandard,
VideoParams::kPixelAspectPALWidescreen,
VideoParams::kPixelAspect1080Anamorphic
const QVector<Rational> VideoParams::k_standard_pixel_aspects = {
VideoParams::k_pixel_aspect_square,
VideoParams::k_pixel_aspect_ntsc_standard,
VideoParams::k_pixel_aspect_ntsc_widescreen,
VideoParams::k_pixel_aspect_pal_standard,
VideoParams::k_pixel_aspect_pal_widescreen,
VideoParams::k_pixel_aspect1080_anamorphic
};
VideoParams::VideoParams()
@@ -74,10 +74,10 @@ VideoParams::VideoParams()
, height_(0)
, depth_(0)
, time_base_(0)
, format_(PixelFormat::INVALID)
, format_(PixelFormat::invalid)
, channel_count_(0)
, pixel_aspect_ratio_(1)
, interlacing_(Interlacing::kInterlaceNone)
, interlacing_(Interlacing::k_interlace_none)
, divider_(1)
{
calculate_effective_size();
@@ -86,7 +86,7 @@ VideoParams::VideoParams()
}
VideoParams::VideoParams(int width, int height, PixelFormat format,
int nb_channels, const rational &pixel_aspect_ratio,
int nb_channels, const Rational &pixel_aspect_ratio,
Interlacing interlacing, int divider)
: width_(width)
, height_(height)
@@ -103,7 +103,7 @@ VideoParams::VideoParams(int width, int height, PixelFormat format,
}
VideoParams::VideoParams(int width, int height, int depth, PixelFormat format,
int nb_channels, const rational &pixel_aspect_ratio,
int nb_channels, const Rational &pixel_aspect_ratio,
VideoParams::Interlacing interlacing, int divider)
: width_(width)
, height_(height)
@@ -119,20 +119,20 @@ VideoParams::VideoParams(int width, int height, int depth, PixelFormat format,
set_defaults_for_footage();
}
void VideoParams::set_channel_count(const std::string &ofxComponent)
void VideoParams::set_channel_count(const std::string &ofx_component)
{
if (ofxComponent == kOfxImageComponentAlpha) {
if (ofx_component == kOfxImageComponentAlpha) {
channel_count_ = 1;
} else if (ofxComponent == kOfxImageComponentRGB) {
channel_count_ = kRGBChannelCount;
} else if (ofxComponent == kOfxImageComponentRGBA) {
channel_count_ = kRGBAChannelCount;
} else if (ofx_component == kOfxImageComponentRGB) {
channel_count_ = k_rgb_channel_count;
} else if (ofx_component == kOfxImageComponentRGBA) {
channel_count_ = k_rgba_channel_count;
}
}
VideoParams::VideoParams(int width, int height, const rational &time_base,
VideoParams::VideoParams(int width, int height, const Rational &time_base,
PixelFormat format, int nb_channels,
const rational &pixel_aspect_ratio,
const Rational &pixel_aspect_ratio,
Interlacing interlacing, int divider)
: width_(width)
, height_(height)
@@ -159,14 +159,14 @@ int VideoParams::generate_auto_divider(qint64 width, qint64 height)
double squared_divider = double(megapixels) / double(target_res);
double divider = qSqrt(squared_divider);
if (divider <= kSupportedDividers.first()) {
return kSupportedDividers.first();
} else if (divider >= kSupportedDividers.last()) {
return kSupportedDividers.last();
if (divider <= k_supported_dividers.first()) {
return k_supported_dividers.first();
} else if (divider >= k_supported_dividers.last()) {
return k_supported_dividers.last();
} else {
for (int i = 1; i < kSupportedDividers.size(); i++) {
int prev_divider = kSupportedDividers.at(i - 1);
int next_divider = kSupportedDividers.at(i);
for (int i = 1; i < k_supported_dividers.size(); i++) {
int prev_divider = k_supported_dividers.at(i - 1);
int next_divider = k_supported_dividers.at(i);
if (divider >= prev_divider && divider <= next_divider) {
double prev_diff = qAbs(prev_divider - divider);
@@ -199,36 +199,36 @@ bool VideoParams::operator!=(const VideoParams &rhs) const
return !(*this == rhs);
}
int VideoParams::GetBytesPerChannel(PixelFormat format)
int VideoParams::get_bytes_per_channel(PixelFormat format)
{
switch (format) {
case PixelFormat::INVALID:
case PixelFormat::COUNT:
case PixelFormat::invalid:
case PixelFormat::count:
break;
case PixelFormat::U8:
case PixelFormat::u8:
return 1;
case PixelFormat::U10:
case PixelFormat::u10:
return 0; // packed format, use GetBytesPerPixel instead
case PixelFormat::U16:
case PixelFormat::F16:
case PixelFormat::u16:
case PixelFormat::f16:
return 2;
case PixelFormat::F32:
case PixelFormat::f32:
return 4;
}
return 0;
}
int VideoParams::GetBytesPerPixel(PixelFormat format, int channels)
int VideoParams::get_bytes_per_pixel(PixelFormat format, int channels)
{
if (format == PixelFormat::U10) {
if (format == PixelFormat::u10) {
// Packed 10-bit RGBA10A2: 4 bytes per RGBA pixel regardless of channel count
return channels == VideoParams::kRGBAChannelCount ? 4 : 0;
return channels == VideoParams::k_rgba_channel_count ? 4 : 0;
}
return GetBytesPerChannel(format) * channels;
return get_bytes_per_channel(format) * channels;
}
QString VideoParams::GetNameForDivider(int div)
QString VideoParams::get_name_for_divider(int div)
{
if (div == 1) {
return QCoreApplication::translate("VideoParams", "Full");
@@ -237,23 +237,23 @@ QString VideoParams::GetNameForDivider(int div)
}
}
QString VideoParams::GetFormatName(PixelFormat format)
QString VideoParams::get_format_name(PixelFormat format)
{
switch (format) {
case PixelFormat::U8:
case PixelFormat::u8:
return QCoreApplication::translate("VideoParams", "8-bit");
case PixelFormat::U10:
case PixelFormat::u10:
return QCoreApplication::translate("VideoParams", "10-bit Packed");
case PixelFormat::U16:
case PixelFormat::u16:
return QCoreApplication::translate("VideoParams", "16-bit Integer");
case PixelFormat::F16:
case PixelFormat::f16:
return QCoreApplication::translate("VideoParams",
"Half-Float (16-bit)");
case PixelFormat::F32:
case PixelFormat::f32:
return QCoreApplication::translate("VideoParams",
"Full-Float (32-bit)");
case PixelFormat::INVALID:
case PixelFormat::COUNT:
case PixelFormat::invalid:
case PixelFormat::count:
break;
}
@@ -261,7 +261,7 @@ QString VideoParams::GetFormatName(PixelFormat format)
.arg(static_cast<int>(format), 0, 16);
}
int VideoParams::GetDividerForTargetResolution(int src_width, int src_height,
int VideoParams::get_divider_for_target_resolution(int src_width, int src_height,
int dst_width, int dst_height)
{
int divider = 0;
@@ -270,8 +270,8 @@ int VideoParams::GetDividerForTargetResolution(int src_width, int src_height,
do {
divider++;
test_width = VideoParams::GetScaledDimension(src_width, divider);
test_height = VideoParams::GetScaledDimension(src_height, divider);
test_width = VideoParams::get_scaled_dimension(src_width, divider);
test_height = VideoParams::get_scaled_dimension(src_height, divider);
} while (test_width > dst_width || test_height > dst_height);
return divider;
@@ -279,10 +279,10 @@ int VideoParams::GetDividerForTargetResolution(int src_width, int src_height,
void VideoParams::calculate_effective_size()
{
effective_width_ = GetScaledDimension(width(), divider_);
effective_height_ = GetScaledDimension(height(), divider_);
effective_width_ = get_scaled_dimension(width(), divider_);
effective_height_ = get_scaled_dimension(height(), divider_);
effective_depth_ = (depth() == 1) ? depth() :
GetScaledDimension(depth(), divider_);
get_scaled_dimension(depth(), divider_);
calculate_square_pixel_width();
}
@@ -298,19 +298,19 @@ void VideoParams::set_defaults_for_footage()
{
enabled_ = true;
stream_index_ = 0;
video_type_ = kVideoTypeVideo;
video_type_ = k_video_type_video;
start_time_ = 0;
duration_ = 0;
premultiplied_alpha_ = false;
x_ = 0;
y_ = 0;
color_range_ = kColorRangeDefault;
color_range_ = k_color_range_default;
}
void VideoParams::calculate_square_pixel_width()
{
if (pixel_aspect_ratio_.denominator() != 0) {
par_width_ = qRound(width_ * pixel_aspect_ratio_.toDouble());
par_width_ = qRound(width_ * pixel_aspect_ratio_.to_double());
} else {
par_width_ = width_;
}
@@ -319,17 +319,17 @@ void VideoParams::calculate_square_pixel_width()
bool VideoParams::is_valid() const
{
return (width() > 0 && height() > 0 && !pixel_aspect_ratio_.isNull() &&
format_ > PixelFormat::INVALID && format_ < PixelFormat::COUNT &&
format_ > PixelFormat::invalid && format_ < PixelFormat::count &&
channel_count_ > 0);
}
QString VideoParams::FrameRateToString(const rational &frame_rate)
QString VideoParams::frame_rate_to_string(const Rational &frame_rate)
{
return QCoreApplication::translate("VideoParams", "%1 FPS")
.arg(frame_rate.toDouble());
.arg(frame_rate.to_double());
}
QStringList VideoParams::GetStandardPixelAspectRatioNames()
QStringList VideoParams::get_standard_pixel_aspect_ratio_names()
{
QStringList strings = {
QCoreApplication::translate("VideoParams", "Square Pixels (%1)"),
@@ -342,25 +342,25 @@ QStringList VideoParams::GetStandardPixelAspectRatioNames()
// Format each
for (int i = 0; i < strings.size(); i++) {
strings.replace(i, FormatPixelAspectRatioString(
strings.at(i), kStandardPixelAspects.at(i)));
strings.replace(i, format_pixel_aspect_ratio_string(
strings.at(i), k_standard_pixel_aspects.at(i)));
}
return strings;
}
QString VideoParams::FormatPixelAspectRatioString(const QString &format,
const rational &ratio)
QString VideoParams::format_pixel_aspect_ratio_string(const QString &format,
const Rational &ratio)
{
return format.arg(QString::number(ratio.toDouble(), 'f', 4));
return format.arg(QString::number(ratio.to_double(), 'f', 4));
}
int VideoParams::GetScaledDimension(int dim, int divider)
int VideoParams::get_scaled_dimension(int dim, int divider)
{
return dim / divider;
}
int64_t VideoParams::get_time_in_timebase_units(const rational &time) const
int64_t VideoParams::get_time_in_timebase_units(const Rational &time) const
{
if (time_base_.isNull()) {
return INT64_MIN; // AV_NOPTS_VALUE
@@ -369,9 +369,9 @@ int64_t VideoParams::get_time_in_timebase_units(const rational &time) const
return Timecode::time_to_timestamp(time, time_base_) + start_time_;
}
void VideoParams::Load(QXmlStreamReader *reader)
void VideoParams::load(QXmlStreamReader *reader)
{
while (XMLReadNextStartElement(reader)) {
while (xml_read_next_start_element(reader)) {
if (reader->name() == QStringLiteral("width")) {
set_width(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("height")) {
@@ -380,7 +380,7 @@ void VideoParams::Load(QXmlStreamReader *reader)
set_depth(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("timebase")) {
set_time_base(
rational::fromString(reader->readElementText().toStdString()));
Rational::from_string(reader->readElementText().toStdString()));
} else if (reader->name() == QStringLiteral("format")) {
set_format(static_cast<PixelFormat::Format>(
reader->readElementText().toInt()));
@@ -388,7 +388,7 @@ void VideoParams::Load(QXmlStreamReader *reader)
set_channel_count(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("pixelaspectratio")) {
set_pixel_aspect_ratio(
rational::fromString(reader->readElementText().toStdString()));
Rational::from_string(reader->readElementText().toStdString()));
} else if (reader->name() == QStringLiteral("interlacing")) {
set_interlacing(static_cast<VideoParams::Interlacing>(
reader->readElementText().toInt()));
@@ -407,7 +407,7 @@ void VideoParams::Load(QXmlStreamReader *reader)
reader->readElementText().toInt()));
} else if (reader->name() == QStringLiteral("framerate")) {
set_frame_rate(
rational::fromString(reader->readElementText().toStdString()));
Rational::from_string(reader->readElementText().toStdString()));
} else if (reader->name() == QStringLiteral("starttime")) {
set_start_time(reader->readElementText().toLongLong());
} else if (reader->name() == QStringLiteral("duration")) {
@@ -425,21 +425,21 @@ void VideoParams::Load(QXmlStreamReader *reader)
}
}
void VideoParams::Save(QXmlStreamWriter *writer) const
void VideoParams::save(QXmlStreamWriter *writer) const
{
writer->writeTextElement(QStringLiteral("width"), QString::number(width_));
writer->writeTextElement(QStringLiteral("height"),
QString::number(height_));
writer->writeTextElement(QStringLiteral("depth"), QString::number(depth_));
writer->writeTextElement(QStringLiteral("timebase"),
QString::fromStdString(time_base_.toString()));
QString::fromStdString(time_base_.to_string()));
writer->writeTextElement(QStringLiteral("format"),
QString::number(format_));
writer->writeTextElement(QStringLiteral("channelcount"),
QString::number(channel_count_));
writer->writeTextElement(
QStringLiteral("pixelaspectratio"),
QString::fromStdString(pixel_aspect_ratio_.toString()));
QString::fromStdString(pixel_aspect_ratio_.to_string()));
writer->writeTextElement(QStringLiteral("interlacing"),
QString::number(interlacing_));
writer->writeTextElement(QStringLiteral("divider"),
@@ -453,7 +453,7 @@ void VideoParams::Save(QXmlStreamWriter *writer) const
writer->writeTextElement(QStringLiteral("videotype"),
QString::number(video_type_));
writer->writeTextElement(QStringLiteral("framerate"),
QString::fromStdString(frame_rate_.toString()));
QString::fromStdString(frame_rate_.to_string()));
writer->writeTextElement(QStringLiteral("starttime"),
QString::number(start_time_));
writer->writeTextElement(QStringLiteral("duration"),
+64 -64
View File
@@ -19,8 +19,8 @@
***/
#ifndef VIDEOPARAMS_H
#define VIDEOPARAMS_H
#ifndef OAK_VIDEOPARAMS_H
#define OAK_VIDEOPARAMS_H
#include <olive/core/core.h>
#include <QVector2D>
@@ -36,30 +36,30 @@ using namespace core;
class VideoParams {
public:
enum Interlacing {
kInterlaceNone,
kInterlacedTopFirst,
kInterlacedBottomFirst
k_interlace_none,
k_interlaced_top_first,
k_interlaced_bottom_first
};
enum Type { kVideoTypeVideo, kVideoTypeStill, kVideoTypeImageSequence };
enum Type { k_video_type_video, k_video_type_still, k_video_type_image_sequence };
enum ColorRange {
kColorRangeLimited, // 16_235
kColorRangeFull, // 0-255
k_color_range_limited, // 16_235
k_color_range_full, // 0-255
kColorRangeDefault = kColorRangeLimited
k_color_range_default = k_color_range_limited
};
VideoParams();
VideoParams(int width, int height, PixelFormat format, int nb_channels,
const rational &pixel_aspect_ratio = 1,
Interlacing interlacing = kInterlaceNone, int divider = 1);
const Rational &pixel_aspect_ratio = 1,
Interlacing interlacing = k_interlace_none, int divider = 1);
VideoParams(int width, int height, int depth, PixelFormat format,
int nb_channels, const rational &pixel_aspect_ratio = 1,
Interlacing interlacing = kInterlaceNone, int divider = 1);
VideoParams(int width, int height, const rational &time_base,
int nb_channels, const Rational &pixel_aspect_ratio = 1,
Interlacing interlacing = k_interlace_none, int divider = 1);
VideoParams(int width, int height, const Rational &time_base,
PixelFormat format, int nb_channels,
const rational &pixel_aspect_ratio = 1,
Interlacing interlacing = kInterlaceNone, int divider = 1);
const Rational &pixel_aspect_ratio = 1,
Interlacing interlacing = k_interlace_none, int divider = 1);
int width() const
{
@@ -117,17 +117,17 @@ public:
return depth_ > 1;
}
const rational &time_base() const
const Rational &time_base() const
{
return time_base_;
}
void set_time_base(const rational &r)
void set_time_base(const Rational &r)
{
time_base_ = r;
}
rational frame_rate_as_time_base() const
Rational frame_rate_as_time_base() const
{
return frame_rate_.flipped();
}
@@ -177,13 +177,13 @@ public:
{
channel_count_ = c;
}
void set_channel_count(const std::string &ofxComponent);
const rational &pixel_aspect_ratio() const
void set_channel_count(const std::string &ofx_component);
const Rational &pixel_aspect_ratio() const
{
return pixel_aspect_ratio_;
}
void set_pixel_aspect_ratio(const rational &r)
void set_pixel_aspect_ratio(const Rational &r)
{
pixel_aspect_ratio_ = r;
validate_pixel_aspect_ratio();
@@ -206,67 +206,67 @@ public:
bool operator==(const VideoParams &rhs) const;
bool operator!=(const VideoParams &rhs) const;
static int GetBytesPerChannel(PixelFormat format);
int GetBytesPerChannel() const
static int get_bytes_per_channel(PixelFormat format);
int get_bytes_per_channel() const
{
return GetBytesPerChannel(format_);
return get_bytes_per_channel(format_);
}
static int GetBytesPerPixel(PixelFormat format, int channels);
int GetBytesPerPixel() const
static int get_bytes_per_pixel(PixelFormat format, int channels);
int get_bytes_per_pixel() const
{
return GetBytesPerPixel(format_, channel_count_);
return get_bytes_per_pixel(format_, channel_count_);
}
static int GetBufferSize(int width, int height, PixelFormat format,
static int get_buffer_size(int width, int height, PixelFormat format,
int channels)
{
return width * height * GetBytesPerPixel(format, channels);
return width * height * get_bytes_per_pixel(format, channels);
}
int GetBufferSize() const
int get_buffer_size() const
{
return GetBufferSize(width_, height_, format_, channel_count_);
return get_buffer_size(width_, height_, format_, channel_count_);
}
static QString GetNameForDivider(int div);
static QString get_name_for_divider(int div);
static bool FormatIsFloat(PixelFormat format)
static bool format_is_float(PixelFormat format)
{
return format.is_float();
}
static QString GetFormatName(PixelFormat format);
static QString get_format_name(PixelFormat format);
static int GetDividerForTargetResolution(int src_width, int src_height,
static int get_divider_for_target_resolution(int src_width, int src_height,
int dst_width, int dst_height);
static const int kInternalChannelCount;
static const int k_internal_channel_count;
static const rational kPixelAspectSquare;
static const rational kPixelAspectNTSCStandard;
static const rational kPixelAspectNTSCWidescreen;
static const rational kPixelAspectPALStandard;
static const rational kPixelAspectPALWidescreen;
static const rational kPixelAspect1080Anamorphic;
static const Rational k_pixel_aspect_square;
static const Rational k_pixel_aspect_ntsc_standard;
static const Rational k_pixel_aspect_ntsc_widescreen;
static const Rational k_pixel_aspect_pal_standard;
static const Rational k_pixel_aspect_pal_widescreen;
static const Rational k_pixel_aspect1080_anamorphic;
static const QVector<rational> kSupportedFrameRates;
static const QVector<rational> kStandardPixelAspects;
static const QVector<int> kSupportedDividers;
static const QVector<Rational> k_supported_frame_rates;
static const QVector<Rational> k_standard_pixel_aspects;
static const QVector<int> k_supported_dividers;
static const int kHSVChannelCount = 3;
static const int kRGBChannelCount = 3;
static const int kRGBAChannelCount = 4;
static const int k_hsv_channel_count = 3;
static const int k_rgb_channel_count = 3;
static const int k_rgba_channel_count = 4;
/**
* @brief Convert rational frame rate (i.e. flipped timebase) to a user-friendly string
* @brief Convert Rational frame rate (i.e. flipped timebase) to a user-friendly string
*/
static QString FrameRateToString(const rational &frame_rate);
static QString frame_rate_to_string(const Rational &frame_rate);
static QStringList GetStandardPixelAspectRatioNames();
static QString FormatPixelAspectRatioString(const QString &format,
const rational &ratio);
static QStringList get_standard_pixel_aspect_ratio_names();
static QString format_pixel_aspect_ratio_string(const QString &format,
const Rational &ratio);
static int GetScaledDimension(int dim, int divider);
static int get_scaled_dimension(int dim, int divider);
bool enabled() const
{
@@ -319,12 +319,12 @@ public:
video_type_ = t;
}
const rational &frame_rate() const
const Rational &frame_rate() const
{
return frame_rate_;
}
void set_frame_rate(const rational &frame_rate)
void set_frame_rate(const Rational &frame_rate)
{
frame_rate_ = frame_rate;
}
@@ -378,11 +378,11 @@ public:
color_range_ = color_range;
}
int64_t get_time_in_timebase_units(const rational &time) const;
int64_t get_time_in_timebase_units(const Rational &time) const;
void Load(QXmlStreamReader *reader);
void load(QXmlStreamReader *reader);
void Save(QXmlStreamWriter *writer) const;
void save(QXmlStreamWriter *writer) const;
private:
void calculate_effective_size();
@@ -396,13 +396,13 @@ private:
int width_;
int height_;
int depth_;
rational time_base_;
Rational time_base_;
PixelFormat format_;
int channel_count_;
rational pixel_aspect_ratio_;
Rational pixel_aspect_ratio_;
Interlacing interlacing_;
@@ -417,7 +417,7 @@ private:
bool enabled_;
int stream_index_;
Type video_type_;
rational frame_rate_;
Rational frame_rate_;
int64_t start_time_;
int64_t duration_;
bool premultiplied_alpha_;
@@ -432,4 +432,4 @@ private:
Q_DECLARE_METATYPE(olive::VideoParams)
Q_DECLARE_METATYPE(olive::VideoParams::Interlacing)
#endif // VIDEOPARAMS_H
#endif // OAK_VIDEOPARAMS_H
+35 -35
View File
@@ -17,21 +17,21 @@ namespace
class BackendVulkanRenderer : public olive::VulkanRenderer {
public:
using olive::VulkanRenderer::VulkanRenderer;
using olive::VulkanRenderer::Blit;
using olive::VulkanRenderer::CreateNativeTexture;
using olive::VulkanRenderer::DestroyInternal;
using olive::VulkanRenderer::DestroyNativeTexture;
using olive::VulkanRenderer::blit;
using olive::VulkanRenderer::create_native_texture;
using olive::VulkanRenderer::destroy_internal;
using olive::VulkanRenderer::destroy_native_texture;
};
// Converts the opaque C ABI handle back to the C++ Vulkan renderer.
BackendVulkanRenderer *Renderer(OakRenderBackendHandle handle)
BackendVulkanRenderer *renderer(OakRenderBackendHandle handle)
{
return static_cast<BackendVulkanRenderer *>(handle);
}
// Interprets ABI QVariant payloads without copying; this ABI version assumes
// the host and backend are built with the same Qt/C++ ABI.
const QVariant &VariantRef(const void *variant)
const QVariant &variant_ref(const void *variant)
{
return *static_cast<const QVariant *>(variant);
}
@@ -49,7 +49,7 @@ oak_renderer_create(void *parent)
OAK_RENDER_BACKEND_EXPORT void
oak_renderer_destroy(OakRenderBackendHandle handle)
{
delete Renderer(handle);
delete renderer(handle);
}
// Reports Vulkan backend capabilities and runtime availability status.
@@ -61,12 +61,12 @@ oak_renderer_get_info(OakRenderBackendHandle handle,
return false;
}
out_info->abi_version = 1;
out_info->kind = OAK_RENDER_BACKEND_VULKAN;
out_info->kind = oak_render_backend_vulkan;
out_info->capabilities =
OAK_RENDER_BACKEND_CAP_TEXTURES | OAK_RENDER_BACKEND_CAP_SHADERS |
OAK_RENDER_BACKEND_CAP_BLIT | OAK_RENDER_BACKEND_CAP_READBACK;
oak_render_backend_cap_textures | oak_render_backend_cap_shaders |
oak_render_backend_cap_blit | oak_render_backend_cap_readback;
out_info->name = "vulkan";
out_info->status = Renderer(handle)->IsAvailable() ? "available" :
out_info->status = renderer(handle)->is_available() ? "available" :
"unavailable";
return true;
}
@@ -76,21 +76,21 @@ oak_renderer_get_info(OakRenderBackendHandle handle,
OAK_RENDER_BACKEND_EXPORT bool
oak_renderer_is_available(OakRenderBackendHandle handle)
{
auto *r = Renderer(handle);
if (!r || r->IsAvailable()) {
return r && r->IsAvailable();
auto *r = renderer(handle);
if (!r || r->is_available()) {
return r && r->is_available();
}
// Try to initialize if not already available
if (r->Init()) {
r->PostInit();
if (r->init()) {
r->post_init();
}
return r->IsAvailable();
return r->is_available();
}
// Initializes the Vulkan device path.
OAK_RENDER_BACKEND_EXPORT bool oak_renderer_init(OakRenderBackendHandle handle)
{
return Renderer(handle)->Init();
return renderer(handle)->init();
}
// Vulkan does not use a QOpenGLContext; the argument is accepted for ABI parity.
@@ -98,28 +98,28 @@ OAK_RENDER_BACKEND_EXPORT void
oak_renderer_init_with_context(OakRenderBackendHandle handle, void *context)
{
Q_UNUSED(context)
Renderer(handle)->Init();
renderer(handle)->init();
}
// Creates reusable Vulkan resources after device initialization.
OAK_RENDER_BACKEND_EXPORT void
oak_renderer_post_init(OakRenderBackendHandle handle)
{
Renderer(handle)->PostInit();
renderer(handle)->post_init();
}
// Reserved for API symmetry; Vulkan cleanup is handled by destroy_internal.
OAK_RENDER_BACKEND_EXPORT void
oak_renderer_post_destroy(OakRenderBackendHandle handle)
{
Renderer(handle)->PostDestroy();
renderer(handle)->post_destroy();
}
// Releases all Vulkan resources owned by the renderer.
OAK_RENDER_BACKEND_EXPORT void
oak_renderer_destroy_internal(OakRenderBackendHandle handle)
{
Renderer(handle)->DestroyInternal();
renderer(handle)->destroy_internal();
}
// Clears a Vulkan texture destination.
@@ -127,7 +127,7 @@ OAK_RENDER_BACKEND_EXPORT void
oak_renderer_clear_destination(OakRenderBackendHandle handle, void *texture,
double r, double g, double b, double a)
{
Renderer(handle)->ClearDestination(static_cast<olive::Texture *>(texture),
renderer(handle)->clear_destination(static_cast<olive::Texture *>(texture),
r, g, b, a);
}
@@ -137,7 +137,7 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_create_native_texture(
int channel_count, const void *data, int linesize, void *out_variant)
{
*static_cast<QVariant *>(out_variant) =
Renderer(handle)->CreateNativeTexture(
renderer(handle)->create_native_texture(
width, height, depth,
static_cast<olive::PixelFormat::Format>(format), channel_count,
data, linesize);
@@ -148,7 +148,7 @@ OAK_RENDER_BACKEND_EXPORT void
oak_renderer_destroy_native_texture(OakRenderBackendHandle handle,
const void *variant)
{
Renderer(handle)->DestroyNativeTexture(VariantRef(variant));
renderer(handle)->destroy_native_texture(variant_ref(variant));
}
// Compiles a Vulkan shader and returns its QVariant handle.
@@ -157,7 +157,7 @@ oak_renderer_create_native_shader(OakRenderBackendHandle handle,
const void *shader_code, void *out_variant)
{
*static_cast<QVariant *>(out_variant) =
Renderer(handle)->CreateNativeShader(
renderer(handle)->create_native_shader(
*static_cast<const olive::ShaderCode *>(shader_code));
}
@@ -166,7 +166,7 @@ OAK_RENDER_BACKEND_EXPORT void
oak_renderer_destroy_native_shader(OakRenderBackendHandle handle,
const void *variant)
{
Renderer(handle)->DestroyNativeShader(VariantRef(variant));
renderer(handle)->destroy_native_shader(variant_ref(variant));
}
// Uploads CPU pixel data into a Vulkan texture.
@@ -175,8 +175,8 @@ oak_renderer_upload_to_texture(OakRenderBackendHandle handle,
const void *variant, const void *video_params,
const void *data, int linesize)
{
Renderer(handle)->UploadToTexture(
VariantRef(variant),
renderer(handle)->upload_to_texture(
variant_ref(variant),
*static_cast<const olive::VideoParams *>(video_params), data, linesize);
}
@@ -185,15 +185,15 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_download_from_texture(
OakRenderBackendHandle handle, const void *variant,
const void *video_params, void *data, int linesize)
{
Renderer(handle)->DownloadFromTexture(
VariantRef(variant),
renderer(handle)->download_from_texture(
variant_ref(variant),
*static_cast<const olive::VideoParams *>(video_params), data, linesize);
}
// Waits for all queued Vulkan work to finish.
OAK_RENDER_BACKEND_EXPORT void oak_renderer_flush(OakRenderBackendHandle handle)
{
Renderer(handle)->Flush();
renderer(handle)->flush();
}
// Reads one pixel from a Vulkan texture.
@@ -203,7 +203,7 @@ oak_renderer_get_pixel_from_texture(OakRenderBackendHandle handle,
void *out_color)
{
*static_cast<olive::Color *>(out_color) =
Renderer(handle)->GetPixelFromTexture(
renderer(handle)->get_pixel_from_texture(
static_cast<olive::Texture *>(texture),
*static_cast<const QPointF *>(point));
}
@@ -215,8 +215,8 @@ OAK_RENDER_BACKEND_EXPORT void oak_renderer_blit(OakRenderBackendHandle handle,
const void *destination_params,
bool clear_destination)
{
Renderer(handle)->Blit(
VariantRef(shader), *static_cast<olive::AcceleratedJob *>(job),
renderer(handle)->blit(
variant_ref(shader), *static_cast<olive::AcceleratedJob *>(job),
static_cast<olive::Texture *>(destination),
*static_cast<const olive::VideoParams *>(destination_params),
clear_destination);
File diff suppressed because it is too large Load Diff
+61 -61
View File
@@ -18,8 +18,8 @@
***************************************************************************/
#ifndef VULKANRENDERER_H
#define VULKANRENDERER_H
#ifndef OAK_VULKANRENDERER_H
#define OAK_VULKANRENDERER_H
#include <vulkan/vulkan.h>
@@ -42,67 +42,67 @@ public:
// Creates the Vulkan instance, logical device, command pool, and descriptor
// pool required for offscreen rendering.
virtual bool Init() override;
virtual bool init() override;
// Creates reusable GPU resources that require a fully initialized device.
virtual void PostInit() override;
virtual void post_init() override;
// Reserved for symmetry with OpenGLRenderer; Vulkan cleanup is handled by
// DestroyInternal().
virtual void PostDestroy() override;
virtual void post_destroy() override;
// Clears either a texture render target or the currently bound output target.
virtual void ClearDestination(olive::Texture *texture = nullptr,
virtual void clear_destination(olive::Texture *texture = nullptr,
double r = 0.0, double g = 0.0,
double b = 0.0, double a = 0.0) override;
// Compiles GLSL to SPIR-V, creates shader modules, and prepares descriptor
// metadata for later blits.
virtual QVariant CreateNativeShader(olive::ShaderCode code) override;
virtual QVariant create_native_shader(olive::ShaderCode code) override;
// Destroys shader modules, descriptor layout, pipeline layout, and cached
// pipelines associated with a shader handle.
virtual void DestroyNativeShader(QVariant shader) override;
virtual void destroy_native_shader(QVariant shader) override;
// Uploads CPU pixel data to a Vulkan image via a staging buffer.
virtual void UploadToTexture(const QVariant &handle,
virtual void upload_to_texture(const QVariant &handle,
const VideoParams &params, const void *data,
int linesize) override;
// Downloads a Vulkan image to CPU memory via a staging buffer.
virtual void DownloadFromTexture(const QVariant &handle,
virtual void download_from_texture(const QVariant &handle,
const VideoParams &params, void *data,
int linesize) override;
// Waits for outstanding device work to complete.
virtual void Flush() override;
virtual void flush() override;
virtual bool IsVulkan() const override
virtual bool is_vulkan() const override
{
return true;
}
// Reads a single texture pixel using a one-pixel transfer readback.
virtual Color GetPixelFromTexture(olive::Texture *texture,
virtual Color get_pixel_from_texture(olive::Texture *texture,
const QPointF &pt) override;
bool IsAvailable() const
bool is_available() const
{
return device_ != VK_NULL_HANDLE;
}
protected:
// Runs one or more fullscreen shader passes into the destination texture.
virtual void Blit(QVariant shader, olive::AcceleratedJob &job,
virtual void blit(QVariant shader, olive::AcceleratedJob &job,
olive::Texture *destination,
VideoParams destination_params,
bool clear_destination) override;
// Creates a Vulkan image/view/memory bundle and optionally uploads initial
// pixel data.
virtual QVariant CreateNativeTexture(int width, int height, int depth,
virtual QVariant create_native_texture(int width, int height, int depth,
PixelFormat format, int channel_count,
const void *data = nullptr,
int linesize = 0) override;
// Releases a Vulkan texture bundle.
virtual void DestroyNativeTexture(QVariant texture) override;
virtual void destroy_native_texture(QVariant texture) override;
// Releases all Vulkan device resources owned by this renderer.
virtual void DestroyInternal() override;
virtual void destroy_internal() override;
private:
struct VulkanTexture;
@@ -111,113 +111,113 @@ private:
struct StagingBuffer;
// Creates the Vulkan instance used for all offscreen work.
bool CreateInstance();
bool create_instance();
// Creates the debug messenger when validation layers are available.
bool CreateDebugMessenger();
bool create_debug_messenger();
// Destroys the debug messenger before the instance is destroyed.
void DestroyDebugMessenger();
void destroy_debug_messenger();
// Validation layer callback; logs errors/warnings so synchronization issues
// are visible before they become GPU hangs.
static VKAPI_ATTR VkBool32 VKAPI_CALL
DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
void *pUserData);
debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
VkDebugUtilsMessageTypeFlagsEXT message_type,
const VkDebugUtilsMessengerCallbackDataEXT *p_callback_data,
void *p_user_data);
// Chooses a graphics-capable physical device and creates the logical device.
bool CreateDevice();
bool create_device();
// Creates a command pool for short-lived command buffers.
bool CreateCommandPool();
bool create_command_pool();
// Creates the descriptor pool used for per-blit UBO/sampler sets.
bool CreateDescriptorPool();
bool create_descriptor_pool();
// Uploads the fullscreen quad vertex buffer used by BlitPass().
bool CreateVertexBuffer();
bool create_vertex_buffer();
// Creates the persistent linear sampler.
bool CreateLinearSampler();
bool create_linear_sampler();
// Creates the persistent nearest-neighbor sampler.
bool CreateNearestSampler();
bool create_nearest_sampler();
// Returns the persistent sampler matching the requested interpolation mode.
VkSampler GetSampler(Texture::Interpolation interpolation) const;
VkSampler get_sampler(Texture::Interpolation interpolation) const;
// Allocates a host-visible staging buffer for upload/download transfers.
bool CreateStagingBuffer(VkDeviceSize size, VkBuffer *out_buffer,
bool create_staging_buffer(VkDeviceSize size, VkBuffer *out_buffer,
VkDeviceMemory *out_memory);
// Destroys a staging buffer pair allocated by CreateStagingBuffer().
void DestroyStagingBuffer(VkBuffer buffer, VkDeviceMemory memory);
void destroy_staging_buffer(VkBuffer buffer, VkDeviceMemory memory);
// Begins a one-shot command buffer and records it immediately.
VkCommandBuffer BeginOneTimeCommands();
VkCommandBuffer begin_one_time_commands();
// Submits and waits for a one-shot command buffer.
void EndOneTimeCommands(VkCommandBuffer cmd);
void end_one_time_commands(VkCommandBuffer cmd);
// Emits an image memory barrier for the subset of layouts this renderer uses.
void TransitionImageLayout(VkCommandBuffer cmd, VkImage image,
void transition_image_layout(VkCommandBuffer cmd, VkImage image,
VkImageLayout old_layout,
VkImageLayout new_layout);
// Records a tightly packed buffer-to-image copy.
void CopyBufferToImage(VkCommandBuffer cmd, VkBuffer buffer, VkImage image,
void copy_buffer_to_image(VkCommandBuffer cmd, VkBuffer buffer, VkImage image,
uint32_t width, uint32_t height, uint32_t depth);
// Records an image-to-buffer copy, optionally reading one pixel offset.
void CopyImageToBuffer(VkCommandBuffer cmd, VkImage image, VkBuffer buffer,
void copy_image_to_buffer(VkCommandBuffer cmd, VkImage image, VkBuffer buffer,
uint32_t width, uint32_t height,
uint32_t offset_x = 0, uint32_t offset_y = 0);
// Converts Oak pixel format/channel metadata to a preferred Vulkan format.
VkFormat PixelFormatToVkFormat(PixelFormat format, int channel_count) const;
VkFormat pixel_format_to_vk_format(PixelFormat format, int channel_count) const;
// Picks a color-attachment-capable format, falling back from RGB to RGBA
// where drivers do not support 3-channel render targets.
VkFormat PickRenderableFormat(PixelFormat format, int channel_count) const;
VkFormat pick_renderable_format(PixelFormat format, int channel_count) const;
// Checks whether a format can be used as a render target.
bool IsColorAttachmentSupported(VkFormat format) const;
bool is_color_attachment_supported(VkFormat format) const;
// Returns the packed byte size for supported VkFormat values.
int GetVkFormatBytesPerPixel(VkFormat format) const;
int get_vk_format_bytes_per_pixel(VkFormat format) const;
// Returns the alpha fill value used when expanding RGB data to RGBA.
float GetFormatMaxAlpha(PixelFormat format) const;
float get_format_max_alpha(PixelFormat format) const;
// Repackages tightly packed pixels when the requested CPU channel count
// differs from the selected GPU format channel count.
void CopyPixelsWithChannelConversion(const void *src, void *dst, int width,
void copy_pixels_with_channel_conversion(const void *src, void *dst, int width,
int height, int depth,
int src_channels, int dst_channels,
PixelFormat format) const;
// Rounds a size up to the requested alignment.
VkDeviceSize AlignSize(VkDeviceSize size, VkDeviceSize alignment) const;
VkDeviceSize align_size(VkDeviceSize size, VkDeviceSize alignment) const;
// Finds a Vulkan memory type matching the requested properties.
uint32_t FindMemoryType(uint32_t type_filter,
uint32_t find_memory_type(uint32_t type_filter,
VkMemoryPropertyFlags properties) const;
// Compiles GLSL source into SPIR-V using shaderc when available.
bool CompileGlslToSpv(const QString &glsl, VkShaderStageFlagBits stage,
bool compile_glsl_to_spv(const QString &glsl, VkShaderStageFlagBits stage,
QByteArray *out_spv);
// Rewrites an Oak GLSL shader into Vulkan-compatible GLSL.
QString ConvertGlslToVulkan(const QString &glsl,
QString convert_glsl_to_vulkan(const QString &glsl,
VkShaderStageFlagBits stage);
// Ensures a shader declares a Vulkan-compatible GLSL version.
QString EnsureGlslVersion450(const QString &glsl) const;
QString ensure_glsl_version450(const QString &glsl) const;
// Extracts uniforms and sampler names from GLSL declarations.
void ExtractUniforms(const QString &glsl,
void extract_uniforms(const QString &glsl,
QVector<UniformInfo> *out_uniforms,
QVector<QString> *out_samplers) const;
// Computes std140 offsets and total UBO size for extracted uniforms.
void ComputeUniformLayout(QVector<UniformInfo> *uniforms) const;
void compute_uniform_layout(QVector<UniformInfo> *uniforms) const;
// Builds the generated uniform block used by rewritten shaders.
QString BuildUboBlock(const QVector<UniformInfo> &uniforms) const;
QString build_ubo_block(const QVector<UniformInfo> &uniforms) const;
// Rewrites standalone uniforms and samplers into explicit UBO/sampler
// bindings accepted by Vulkan GLSL.
QString
RewriteShaderWithUbo(const QString &glsl,
rewrite_shader_with_ubo(const QString &glsl,
const QVector<UniformInfo> &all_uniforms,
const QHash<QString, int> &sampler_bindings) const;
// Returns std140 storage size for a supported GLSL type.
VkDeviceSize GetStd140Size(const QString &type) const;
VkDeviceSize get_std140_size(const QString &type) const;
// Returns std140 alignment for a supported GLSL type.
VkDeviceSize GetStd140Alignment(const QString &type) const;
VkDeviceSize get_std140_alignment(const QString &type) const;
// Creates or retrieves the graphics pipeline for a shader/render format pair.
bool CreatePipelineForShader(VulkanShader *shader,
bool create_pipeline_for_shader(VulkanShader *shader,
const VideoParams &dest_params,
VkFormat render_pass_format);
// Caches simple single-color-attachment render passes by format/clear mode.
VkRenderPass GetOrCreateRenderPass(VkFormat format, bool clear);
VkRenderPass get_or_create_render_pass(VkFormat format, bool clear);
struct TextureBinding {
QString name;
@@ -226,7 +226,7 @@ private:
};
// Executes one fullscreen pass with the provided texture bindings and UBO.
void BlitPass(VulkanShader *shader, VulkanTexture *dest_tex,
void blit_pass(VulkanShader *shader, VulkanTexture *dest_tex,
const QVector<TextureBinding> &bindings,
const QByteArray &ubo_data,
const VideoParams &destination_params, bool clear_destination,
@@ -269,9 +269,9 @@ private:
quint64 next_shader_id_ = 1;
QHash<quint64, VulkanShader *> shaders_;
static const int kMaxDescriptorSets = 1024;
static const int k_max_descriptor_sets = 1024;
};
}
#endif // VULKANRENDERER_H
#endif // OAK_VULKANRENDERER_H
+160 -160
View File
@@ -66,7 +66,7 @@ namespace
{
#ifdef Q_OS_LINUX
void PrintBacktrace(int sig)
void print_backtrace(int sig)
{
void *array[50];
size_t size = backtrace(array, 50);
@@ -77,12 +77,12 @@ void PrintBacktrace(int sig)
}
#endif
constexpr int kProtocolVersion = 1;
constexpr int kDefaultWidth = 1920;
constexpr int kDefaultHeight = 1080;
constexpr int kDefaultFrameRate = 24;
constexpr int k_protocol_version = 1;
constexpr int k_default_width = 1920;
constexpr int k_default_height = 1080;
constexpr int k_default_frame_rate = 24;
void InstallSurfaceFormat()
void install_surface_format()
{
QSurfaceFormat format;
format.setVersion(3, 2);
@@ -91,17 +91,17 @@ void InstallSurfaceFormat()
QSurfaceFormat::setDefaultFormat(format);
}
void LogError(const QString &message)
void log_error(const QString &message)
{
const QByteArray line = QByteArray("worker: ") + message.toUtf8() + '\n';
fwrite(line.constData(), 1, size_t(line.size()), stderr);
fflush(stderr);
}
QJsonObject ErrorMessage(const QString &message, qint64 ticket_id = 0)
QJsonObject error_message(const QString &message, qint64 ticket_id = 0)
{
QJsonObject o;
o["type"] = olive::ipc::msgtype::kError;
o["type"] = olive::ipc::msgtype::k_error;
o["message"] = message;
if (ticket_id) {
o["ticket"] = double(ticket_id);
@@ -120,13 +120,13 @@ public:
~RenderWorker()
{
project_.reset();
olive::ProjectSerializer::Destroy();
olive::DiskManager::DestroyInstance();
olive::FrameManager::DestroyInstance();
olive::NodeFactory::Destroy();
olive::ProjectSerializer::destroy();
olive::DiskManager::destroy_instance();
olive::FrameManager::destroy_instance();
olive::NodeFactory::destroy();
}
bool InitializeRuntime()
bool initialize_runtime()
{
// Create a minimal Core instance so that code paths calling Core::instance()
// (e.g. ViewerOutput::data for timecode display) do not dereference null.
@@ -135,19 +135,19 @@ public:
new olive::Core(olive::Core::CoreParams());
}
olive::Config::Load();
olive::NodeFactory::Initialize();
olive::ColorManager::SetUpDefaultConfig();
olive::FrameManager::CreateInstance();
olive::DiskManager::CreateInstance();
olive::ProjectSerializer::Initialize();
olive::Config::load();
olive::NodeFactory::initialize();
olive::ColorManager::set_up_default_config();
olive::FrameManager::create_instance();
olive::DiskManager::create_instance();
olive::ProjectSerializer::initialize();
return true;
}
bool SendStartupHandshake()
bool send_startup_handshake()
{
olive::ipc::HandshakeMsg hs;
hs.protocol_version = kProtocolVersion;
hs.protocol_version = k_protocol_version;
hs.shm_key = QString();
hs.input_shm_key = QString();
hs.input_slots = 0;
@@ -155,12 +155,12 @@ public:
hs.slot_data_bytes = 0;
hs.input_slot_data_bytes = 0;
QJsonObject handshake = hs.ToJson();
QJsonObject handshake = hs.to_json();
QOpenGLContext *ctx = nullptr;
#ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND
if (auto *dynamic_renderer =
dynamic_cast<olive::DynamicRenderer *>(renderer_)) {
ctx = dynamic_renderer->OpenGLContext();
ctx = dynamic_renderer->open_gl_context();
} else
#endif
{
@@ -172,52 +172,52 @@ public:
handshake["gl_minor"] = fmt.minorVersion();
}
return Write(handshake);
return write(handshake);
}
bool Handle(const QJsonObject &message)
bool handle(const QJsonObject &message)
{
const QString type = message["type"].toString();
if (type == QLatin1String(olive::ipc::msgtype::kHandshake)) {
if (type == QLatin1String(olive::ipc::msgtype::k_handshake)) {
olive::ipc::HandshakeMsg hs;
if (!olive::ipc::HandshakeMsg::FromJson(message, &hs)) {
return Write(
ErrorMessage(QStringLiteral("invalid handshake message")));
if (!olive::ipc::HandshakeMsg::from_json(message, &hs)) {
return write(
error_message(QStringLiteral("invalid handshake message")));
}
return AttachOutputPool(hs);
return attach_output_pool(hs);
}
if (type == QLatin1String(olive::ipc::msgtype::kLoadGraph)) {
if (type == QLatin1String(olive::ipc::msgtype::k_load_graph)) {
olive::ipc::LoadGraphMsg load;
if (!olive::ipc::LoadGraphMsg::FromJson(message, &load)) {
return Write(
ErrorMessage(QStringLiteral("invalid load_graph message")));
if (!olive::ipc::LoadGraphMsg::from_json(message, &load)) {
return write(
error_message(QStringLiteral("invalid load_graph message")));
}
return LoadGraph(load.path);
return load_graph(load.path);
}
if (type == QLatin1String(olive::ipc::msgtype::kRenderFrame)) {
if (type == QLatin1String(olive::ipc::msgtype::k_render_frame)) {
olive::ipc::RenderFrameMsg render;
if (!olive::ipc::RenderFrameMsg::FromJson(message, &render)) {
return Write(ErrorMessage(
if (!olive::ipc::RenderFrameMsg::from_json(message, &render)) {
return write(error_message(
QStringLiteral("invalid render_frame message")));
}
return RenderFrame(render);
return render_frame(render);
}
if (type == QLatin1String(olive::ipc::msgtype::kCancel)) {
if (type == QLatin1String(olive::ipc::msgtype::k_cancel)) {
// Stage 5 wires cancellation into in-flight jobs. Stage 2 has only synchronous single-frame work.
return true;
}
if (type == QLatin1String(olive::ipc::msgtype::kShutdown)) {
if (type == QLatin1String(olive::ipc::msgtype::k_shutdown)) {
shutdown_requested_ = true;
return true;
}
return Write(
ErrorMessage(QStringLiteral("unknown message type: %1").arg(type)));
return write(
error_message(QStringLiteral("unknown message type: %1").arg(type)));
}
bool shutdown_requested() const
@@ -226,67 +226,67 @@ public:
}
private:
bool Write(const QJsonObject &message)
bool write(const QJsonObject &message)
{
const bool ok = olive::ipc::WriteMessage(out_, message);
const bool ok = olive::ipc::write_message(out_, message);
out_->flush();
return ok;
}
bool AttachOutputPool(const olive::ipc::HandshakeMsg &hs)
bool attach_output_pool(const olive::ipc::HandshakeMsg &hs)
{
if (hs.protocol_version != kProtocolVersion) {
return Write(
ErrorMessage(QStringLiteral("unsupported protocol version %1")
if (hs.protocol_version != k_protocol_version) {
return write(
error_message(QStringLiteral("unsupported protocol version %1")
.arg(hs.protocol_version)));
}
if (hs.shm_key.isEmpty() || hs.output_slots <= 0 ||
hs.slot_data_bytes <= 0) {
return Write(ErrorMessage(QStringLiteral(
return write(error_message(QStringLiteral(
"handshake missing output shared-memory geometry")));
}
const size_t bytes = olive::ipc::FrameSlotPool::BytesNeeded(
const size_t bytes = olive::ipc::FrameSlotPool::bytes_needed(
uint32_t(hs.output_slots), size_t(hs.slot_data_bytes));
if (!output_region_.Open(hs.shm_key, bytes,
olive::ipc::SharedMemoryRegion::kAttach)) {
return Write(ErrorMessage(
if (!output_region_.open(hs.shm_key, bytes,
olive::ipc::SharedMemoryRegion::k_attach)) {
return write(error_message(
QStringLiteral("failed to attach shared memory: %1")
.arg(output_region_.error())));
}
output_pool_ = olive::ipc::FrameSlotPool::Attach(output_region_.data());
if (!output_pool_->IsValid()) {
output_region_.Close();
output_pool_ = olive::ipc::FrameSlotPool::attach(output_region_.data());
if (!output_pool_->is_valid()) {
output_region_.close();
output_pool_.reset();
return Write(ErrorMessage(QStringLiteral(
return write(error_message(QStringLiteral(
"shared memory does not contain a frame slot pool")));
}
input_pool_.reset();
input_region_.Close();
input_region_.close();
if (hs.input_slots > 0) {
if (hs.input_shm_key.isEmpty() || hs.input_slot_data_bytes <= 0) {
return Write(ErrorMessage(QStringLiteral(
return write(error_message(QStringLiteral(
"handshake missing input shared-memory geometry")));
}
const size_t input_bytes = olive::ipc::FrameSlotPool::BytesNeeded(
const size_t input_bytes = olive::ipc::FrameSlotPool::bytes_needed(
uint32_t(hs.input_slots), size_t(hs.input_slot_data_bytes));
if (!input_region_.Open(hs.input_shm_key, input_bytes,
olive::ipc::SharedMemoryRegion::kAttach)) {
return Write(ErrorMessage(
if (!input_region_.open(hs.input_shm_key, input_bytes,
olive::ipc::SharedMemoryRegion::k_attach)) {
return write(error_message(
QStringLiteral("failed to attach input shared memory: %1")
.arg(input_region_.error())));
}
input_pool_ =
olive::ipc::FrameSlotPool::Attach(input_region_.data());
if (!input_pool_->IsValid()) {
input_region_.Close();
olive::ipc::FrameSlotPool::attach(input_region_.data());
if (!input_pool_->is_valid()) {
input_region_.close();
input_pool_.reset();
return Write(ErrorMessage(QStringLiteral(
return write(error_message(QStringLiteral(
"input shared memory does not contain a frame slot pool")));
}
}
@@ -294,24 +294,24 @@ private:
return true;
}
bool LoadGraph(const QString &path)
bool load_graph(const QString &path)
{
{
QFileInfo fi(path);
if (!fi.exists()) {
LogError(
log_error(
QStringLiteral("LoadGraph: graph file does not exist: %1")
.arg(path));
return Write(ErrorMessage(
return write(error_message(
QStringLiteral("graph file does not exist: %1").arg(path)));
}
if (fi.size() == 0) {
LogError(QStringLiteral("LoadGraph: graph file is empty: %1")
log_error(QStringLiteral("LoadGraph: graph file is empty: %1")
.arg(path));
return Write(ErrorMessage(
return write(error_message(
QStringLiteral("graph file is empty: %1").arg(path)));
}
LogError(
log_error(
QStringLiteral("LoadGraph: loading %1 (%2 bytes, readable=%3)")
.arg(path)
.arg(fi.size())
@@ -324,19 +324,19 @@ private:
// Initialize() first triggers Q_ASSERT(!root_) in Project::Load.
olive::ProjectSerializer::Result result =
olive::ProjectSerializer::Load(loaded.get(), path,
olive::ProjectSerializer::kProject);
if (result != olive::ProjectSerializer::kSuccess) {
return Write(
ErrorMessage(QStringLiteral("failed to load graph %1: %2")
.arg(path, result.GetDetails())));
olive::ProjectSerializer::load(loaded.get(), path,
olive::ProjectSerializer::k_project);
if (result != olive::ProjectSerializer::k_success) {
return write(
error_message(QStringLiteral("failed to load graph %1: %2")
.arg(path, result.get_details())));
}
project_ = std::move(loaded);
node_by_token_.clear();
color_processor_cache_.clear();
const auto &data = result.GetLoadData();
const auto &data = result.get_load_data();
for (auto it = data.node_ptrs.cbegin(); it != data.node_ptrs.cend();
++it) {
node_by_token_.insert(QString::number(it.key()), it.value());
@@ -351,10 +351,10 @@ private:
QJsonObject ack;
ack["type"] = QStringLiteral("graph_loaded");
ack["nodes"] = node_by_token_.size();
return Write(ack);
return write(ack);
}
olive::Node *FindNode(const QString &token) const
olive::Node *find_node(const QString &token) const
{
if (olive::Node *node = node_by_token_.value(token, nullptr)) {
return node;
@@ -369,24 +369,24 @@ private:
return nullptr;
}
bool RenderFrame(const olive::ipc::RenderFrameMsg &message)
bool render_frame(const olive::ipc::RenderFrameMsg &message)
{
if (!project_) {
return Write(ErrorMessage(
return write(error_message(
QStringLiteral("render_frame received before load_graph"),
message.ticket_id));
}
if (!output_pool_ || !output_pool_->IsValid()) {
return Write(ErrorMessage(
if (!output_pool_ || !output_pool_->is_valid()) {
return write(error_message(
QStringLiteral(
"render_frame received before output shm handshake"),
message.ticket_id));
}
olive::Node *node = FindNode(message.node_uuid);
olive::Node *node = find_node(message.node_uuid);
if (!node) {
return Write(
ErrorMessage(QStringLiteral("render node not found: %1")
return write(
error_message(QStringLiteral("render node not found: %1")
.arg(message.node_uuid),
message.ticket_id));
}
@@ -397,8 +397,8 @@ private:
QVector<int>{ message.input_slot } :
message.input_slots;
if (!requested_input_slots.isEmpty()) {
if (!input_pool_ || !input_pool_->IsValid()) {
return Write(ErrorMessage(
if (!input_pool_ || !input_pool_->is_valid()) {
return write(error_message(
QStringLiteral(
"render_frame referenced input slot without input pool"),
message.ticket_id));
@@ -408,65 +408,65 @@ private:
if (requested_slot < 0 ||
requested_slot >= int(input_pool_->slot_count())) {
for (int slot : input_slots) {
input_pool_->Release(uint32_t(slot));
input_pool_->release(uint32_t(slot));
}
return Write(ErrorMessage(
return write(error_message(
QStringLiteral("input slot index out of range"),
message.ticket_id));
}
uint32_t consumed_slot = 0;
if (!input_pool_->Consume(&consumed_slot)) {
if (!input_pool_->consume(&consumed_slot)) {
for (int slot : input_slots) {
input_pool_->Release(uint32_t(slot));
input_pool_->release(uint32_t(slot));
}
return Write(
ErrorMessage(QStringLiteral("input slot was not ready"),
return write(
error_message(QStringLiteral("input slot was not ready"),
message.ticket_id));
}
if (int(consumed_slot) != requested_slot) {
input_pool_->Release(consumed_slot);
input_pool_->release(consumed_slot);
for (int slot : input_slots) {
input_pool_->Release(uint32_t(slot));
input_pool_->release(uint32_t(slot));
}
return Write(ErrorMessage(
return write(error_message(
QStringLiteral("input slot order mismatch"),
message.ticket_id));
}
input_slots.append(int(consumed_slot));
const olive::ipc::FrameSlotMeta *meta =
input_pool_->Meta(consumed_slot);
input_pool_->meta(consumed_slot);
if (meta) {
}
}
}
olive::VideoParams vparams(
message.width > 0 ? message.width : kDefaultWidth,
message.height > 0 ? message.height : kDefaultHeight,
olive::rational(1, kDefaultFrameRate),
message.width > 0 ? message.width : k_default_width,
message.height > 0 ? message.height : k_default_height,
olive::Rational(1, k_default_frame_rate),
message.format >= 0 ? olive::PixelFormat::Format(message.format) :
olive::PixelFormat::F32,
olive::PixelFormat::f32,
message.channel_count > 0 ? message.channel_count :
olive::VideoParams::kRGBAChannelCount);
olive::VideoParams::k_rgba_channel_count);
olive::RenderTicketPtr ticket = std::make_shared<olive::RenderTicket>();
ticket->setProperty("node", olive::QtUtils::PtrToValue(node));
ticket->setProperty("node", olive::QtUtils::ptr_to_value(node));
ticket->setProperty("time",
QVariant::fromValue(olive::rational(
QVariant::fromValue(olive::Rational(
int(message.time_num), int(message.time_den))));
ticket->setProperty("size", QSize(message.width, message.height));
ticket->setProperty("matrix", QMatrix4x4());
ticket->setProperty("format",
message.format >= 0 ?
olive::PixelFormat::Format(message.format) :
olive::PixelFormat::INVALID);
olive::PixelFormat::invalid);
ticket->setProperty("usecache", false);
ticket->setProperty("channelcount", message.channel_count);
ticket->setProperty("mode", olive::RenderMode::Mode(message.mode));
ticket->setProperty("type", olive::RenderManager::kTypeVideo);
ticket->setProperty("colormanager", olive::QtUtils::PtrToValue(
ticket->setProperty("type", olive::RenderManager::k_type_video);
ticket->setProperty("colormanager", olive::QtUtils::ptr_to_value(
project_->color_manager()));
{
@@ -489,9 +489,9 @@ private:
} else {
transform = olive::ColorTransform(message.color_output);
}
color_output = olive::ColorProcessor::Create(
color_output = olive::ColorProcessor::create(
project_->color_manager(),
project_->color_manager()->GetReferenceColorSpace(),
project_->color_manager()->get_reference_color_space(),
transform);
if (color_output) {
color_processor_cache_.insert(cache_key, color_output);
@@ -504,16 +504,16 @@ private:
ticket->setProperty("vparam", QVariant::fromValue(vparams));
ticket->setProperty("aparam",
QVariant::fromValue(olive::AudioParams()));
ticket->setProperty("return", olive::RenderManager::kFrame);
ticket->setProperty("return", olive::RenderManager::k_frame);
ticket->setProperty("cache", QString());
ticket->setProperty("cachetimebase",
QVariant::fromValue(olive::rational(1)));
QVariant::fromValue(olive::Rational(1)));
ticket->setProperty("cacheid", QVariant::fromValue(QUuid()));
ticket->setProperty("multicam", olive::QtUtils::PtrToValue(
ticket->setProperty("multicam", olive::QtUtils::ptr_to_value(
static_cast<void *>(nullptr)));
ticket->setProperty(
"ipc_input_pool",
olive::QtUtils::PtrToValue(input_pool_ ?
olive::QtUtils::ptr_to_value(input_pool_ ?
static_cast<void *>(&*input_pool_) :
static_cast<void *>(nullptr)));
QVariantList input_slot_values;
@@ -525,44 +525,44 @@ private:
ticket->setProperty("ipc_input_slot",
input_slots.isEmpty() ? -1 : input_slots.front());
ticket->Start();
olive::RenderProcessor::Process(ticket, renderer_, nullptr,
ticket->start();
olive::RenderProcessor::process(ticket, renderer_, nullptr,
&shader_cache_);
for (int slot : input_slots) {
input_pool_->Release(uint32_t(slot));
input_pool_->release(uint32_t(slot));
}
if (!ticket->HasResult()) {
return Write(ErrorMessage(
if (!ticket->has_result()) {
return write(error_message(
QStringLiteral("render produced no frame"), message.ticket_id));
}
olive::FramePtr frame = ticket->Get().value<olive::FramePtr>();
olive::FramePtr frame = ticket->get().value<olive::FramePtr>();
if (!frame || !frame->is_allocated()) {
return Write(ErrorMessage(QStringLiteral("render result was empty"),
return write(error_message(QStringLiteral("render result was empty"),
message.ticket_id));
}
uint32_t slot = 0;
if (!output_pool_->Acquire(&slot)) {
return Write(
ErrorMessage(QStringLiteral("no free output frame slot"),
if (!output_pool_->acquire(&slot)) {
return write(
error_message(QStringLiteral("no free output frame slot"),
message.ticket_id));
}
const int data_size = frame->linesize_bytes() * frame->height();
if (data_size > int(output_pool_->slot_data_bytes())) {
output_pool_->Release(slot);
LogError(QString("Output frame size") + QString::number(data_size));
LogError(QString("Slot size") +
output_pool_->release(slot);
log_error(QString("Output frame size") + QString::number(data_size));
log_error(QString("Slot size") +
QString::number(output_pool_->slot_data_bytes()));
return Write(ErrorMessage(
return write(error_message(
QStringLiteral("rendered frame does not fit output slot "),
message.ticket_id));
}
std::memcpy(output_pool_->SlotData(slot), frame->const_data(),
std::memcpy(output_pool_->slot_data(slot), frame->const_data(),
size_t(data_size));
olive::ipc::FrameSlotMeta *meta = output_pool_->Meta(slot);
olive::ipc::FrameSlotMeta *meta = output_pool_->meta(slot);
meta->id = message.ticket_id;
meta->time_num = frame->timestamp().numerator();
meta->time_den = frame->timestamp().denominator();
@@ -573,16 +573,16 @@ private:
meta->linesize = frame->linesize_bytes();
meta->data_size = data_size;
if (!output_pool_->Publish(slot)) {
output_pool_->Release(slot);
return Write(ErrorMessage(
if (!output_pool_->publish(slot)) {
output_pool_->release(slot);
return write(error_message(
QStringLiteral("failed to publish output frame slot"),
message.ticket_id));
}
olive::ipc::FrameReadyMsg ready;
ready.ticket_id = message.ticket_id;
ready.output_slot = int(slot);
return Write(ready.ToJson());
return write(ready.to_json());
}
olive::Renderer *renderer_;
@@ -604,7 +604,7 @@ int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
InstallSurfaceFormat();
install_surface_format();
QGuiApplication app(argc, argv);
@@ -625,36 +625,36 @@ int main(int argc, char *argv[])
}
#ifdef Q_OS_LINUX
std::signal(SIGSEGV, PrintBacktrace);
std::signal(SIGABRT, PrintBacktrace);
std::signal(SIGFPE, PrintBacktrace);
std::signal(SIGSEGV, print_backtrace);
std::signal(SIGABRT, print_backtrace);
std::signal(SIGFPE, print_backtrace);
#endif
QFile in;
QFile out;
if (!in.open(stdin, QIODevice::ReadOnly | QIODevice::Unbuffered) ||
!out.open(stdout, QIODevice::WriteOnly | QIODevice::Unbuffered)) {
LogError(QStringLiteral("failed to open stdio control pipes"));
log_error(QStringLiteral("failed to open stdio control pipes"));
return 1;
}
olive::Renderer *renderer;
#ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND
auto *dynamic_renderer = new olive::DynamicRenderer(backend);
if (dynamic_renderer->Init()) {
dynamic_renderer->PostInit();
if (dynamic_renderer->init()) {
dynamic_renderer->post_init();
renderer = dynamic_renderer;
} else {
delete dynamic_renderer;
qWarning() << "Failed to initialize dynamic" << backend
<< "backend, falling back to direct OpenGL renderer";
renderer = new olive::OpenGLRenderer();
if (!renderer->Init()) {
LogError(QStringLiteral("failed to initialize OpenGL renderer"));
if (!renderer->init()) {
log_error(QStringLiteral("failed to initialize OpenGL renderer"));
delete renderer;
return 1;
}
renderer->PostInit();
renderer->post_init();
}
#else
renderer = new olive::OpenGLRenderer();
@@ -674,7 +674,7 @@ int main(int argc, char *argv[])
#ifdef OAK_ENABLE_DYNAMIC_RENDER_BACKEND
if (auto *loaded_renderer =
dynamic_cast<olive::DynamicRenderer *>(renderer)) {
ctx = loaded_renderer->OpenGLContext();
ctx = loaded_renderer->open_gl_context();
} else
#endif
{
@@ -685,9 +685,9 @@ int main(int argc, char *argv[])
}
}
if (!renderer_valid) {
LogError(QStringLiteral("OpenGL context is not valid after init"));
renderer->Destroy();
renderer->PostDestroy();
log_error(QStringLiteral("OpenGL context is not valid after init"));
renderer->destroy();
renderer->post_destroy();
delete renderer;
return 1;
}
@@ -695,7 +695,7 @@ int main(int argc, char *argv[])
int exit_code = 0;
{
RenderWorker worker(renderer, &out);
if (!worker.InitializeRuntime() || !worker.SendStartupHandshake()) {
if (!worker.initialize_runtime() || !worker.send_startup_handshake()) {
exit_code = 1;
} else {
QByteArray buffer;
@@ -709,10 +709,10 @@ int main(int argc, char *argv[])
while (true) {
QJsonObject message;
bool ok = true;
if (!olive::ipc::ReadMessage(&buffer, &message, &ok)) {
if (!olive::ipc::read_message(&buffer, &message, &ok)) {
if (!ok) {
olive::ipc::WriteMessage(
&out, ErrorMessage(QStringLiteral(
olive::ipc::write_message(
&out, error_message(QStringLiteral(
"malformed control message")));
out.flush();
continue;
@@ -720,7 +720,7 @@ int main(int argc, char *argv[])
break;
}
if (!worker.Handle(message)) {
if (!worker.handle(message)) {
exit_code = 1;
break;
}
@@ -729,8 +729,8 @@ int main(int argc, char *argv[])
}
}
renderer->Destroy();
renderer->PostDestroy();
renderer->destroy();
renderer->post_destroy();
delete renderer;
return exit_code;