remove shifts, operations, and make caches node-agnostic

This commit is contained in:
itsmattkc
2022-05-16 19:53:38 -07:00
parent 70a4f7e749
commit e0bb31b199
26 changed files with 124 additions and 708 deletions
+7 -19
View File
@@ -48,11 +48,13 @@ Node::Node() :
can_be_deleted_(true),
override_color_(-1),
folder_(nullptr),
operation_stack_(0),
cache_result_(false),
flags_(kNone)
{
AddInput(kEnabledInput, NodeValue::kBoolean, true);
video_cache_ = new FrameHashCache(this);
audio_cache_ = new AudioPlaybackCache(this);
}
Node::~Node()
@@ -933,18 +935,6 @@ void Node::InvalidateCache(const TimeRange &range, const QString &from, int elem
SendInvalidateCache(range, options);
}
void Node::BeginOperation()
{
// Increase operation stack
operation_stack_++;
}
void Node::EndOperation()
{
// Decrease operation stack
operation_stack_--;
}
TimeRange Node::InputTimeAdjustment(const QString &, int, const TimeRange &input_time) const
{
// Default behavior is no time adjustment at all
@@ -1118,13 +1108,11 @@ Node *Node::CopyNodeInGraph(Node *node, MultiUndoCommand *command)
void Node::SendInvalidateCache(const TimeRange &range, const InvalidateCacheOptions &options)
{
if (GetOperationStack() == 0) {
for (const OutputConnection& conn : output_connections_) {
// Send clear cache signal to the Node
const NodeInput& in = conn.second;
for (const OutputConnection& conn : output_connections_) {
// Send clear cache signal to the Node
const NodeInput& in = conn.second;
in.node()->InvalidateCache(range, in.input(), in.element(), options);
}
in.node()->InvalidateCache(range, in.input(), in.element(), options);
}
}
+16 -20
View File
@@ -39,6 +39,8 @@
#include "node/inputimmediate.h"
#include "node/param.h"
#include "render/audioparams.h"
#include "render/audioplaybackcache.h"
#include "render/framehashcache.h"
#include "render/job/generatejob.h"
#include "render/job/samplejob.h"
#include "render/job/shaderjob.h"
@@ -219,6 +221,16 @@ public:
return HasInputWithID(id);
}
FrameHashCache* video_frame_cache() const
{
return video_cache_;
}
AudioPlaybackCache* audio_playback_cache() const
{
return audio_cache_;
}
struct Position
{
Position(const QPointF &p = QPointF(0, 0), bool e = false)
@@ -798,19 +810,6 @@ public:
InvalidateCache(range, from.input(), from.element(), options);
}
/**
* @brief Limits cache invalidation temporarily
*
* If you intend to do a number of operations in quick succession, you can optimize it by running
* this function with EndOperation().
*/
virtual void BeginOperation();
/**
* @brief Stops limiting cache invalidation and flushes changes
*/
virtual void EndOperation();
/**
* @brief Adjusts time that should be sent to nodes connected to certain inputs.
*
@@ -1030,11 +1029,6 @@ protected:
*/
void IgnoreInvalidationsFrom(const QString &input_id);
int GetOperationStack() const
{
return operation_stack_;
}
enum GizmoScaleHandles {
kGizmoScaleTopLeft,
kGizmoScaleTopCenter,
@@ -1392,8 +1386,6 @@ private:
Folder* folder_;
int operation_stack_;
bool cache_result_;
QMap<InputElementPair, ValueHint> value_hints_;
@@ -1406,6 +1398,10 @@ private:
QString effect_input_;
FrameHashCache *video_cache_;
AudioPlaybackCache *audio_cache_;
private slots:
/**
* @brief Slot when a keyframe's time changes to keep the keyframes correctly sorted by time
-24
View File
@@ -406,10 +406,6 @@ QVector<Block *> Track::BlocksAtTimeRange(const TimeRange &range) const
void Track::InvalidateCache(const TimeRange& range, const QString& from, int element, InvalidateCacheOptions options)
{
if (GetOperationStack() != 0) {
return;
}
TimeRange limited;
const Block* b;
@@ -465,69 +461,49 @@ void Track::InsertBlockAfter(Block *block, Block *before)
void Track::PrependBlock(Block *block)
{
BeginOperation();
InputArrayPrepend(kBlockInput);
Node::ConnectEdge(block, NodeInput(this, kBlockInput, 0));
EndOperation();
// Everything has shifted at this point
Node::InvalidateCache(TimeRange(0, track_length()), kBlockInput);
}
void Track::InsertBlockAtIndex(Block *block, int index)
{
BeginOperation();
int insert_index = GetArrayIndexFromCacheIndex(index);
InputArrayInsert(kBlockInput, insert_index);
Node::ConnectEdge(block, NodeInput(this, kBlockInput, insert_index));
EndOperation();
Node::InvalidateCache(TimeRange(block->in(), track_length()), kBlockInput);
}
void Track::AppendBlock(Block *block)
{
BeginOperation();
InputArrayAppend(kBlockInput);
Node::ConnectEdge(block, NodeInput(this, kBlockInput, InputArraySize(kBlockInput) - 1));
EndOperation();
// Invalidate area that block was added to
Node::InvalidateCache(TimeRange(block->in(), block->out()), kBlockInput);
}
void Track::RippleRemoveBlock(Block *block)
{
BeginOperation();
rational remove_in = block->in();
rational remove_out = block->out();
InputArrayRemove(kBlockInput, GetArrayIndexFromBlock(block));
EndOperation();
Node::InvalidateCache(TimeRange(remove_in, qMax(track_length(), remove_out)), kBlockInput);
}
void Track::ReplaceBlock(Block *old, Block *replace)
{
BeginOperation();
int index_of_old_block = GetArrayIndexFromBlock(old);
DisconnectEdge(old, NodeInput(this, kBlockInput, index_of_old_block));
ConnectEdge(replace, NodeInput(this, kBlockInput, index_of_old_block));
EndOperation();
if (old->length() == replace->length()) {
Node::InvalidateCache(TimeRange(replace->in(), replace->out()), kBlockInput);
} else {
+4 -42
View File
@@ -40,8 +40,6 @@ ViewerOutput::ViewerOutput(bool create_buffer_inputs, bool create_default_stream
last_length_(0),
video_length_(0),
audio_length_(0),
video_frame_cache_(this),
audio_playback_cache_(this),
video_cache_enabled_(true),
audio_cache_enabled_(true)
{
@@ -229,30 +227,6 @@ void ViewerOutput::set_default_parameters()
SetVideoAutoCacheEnabled(OLIVE_CONFIG("DefaultSequenceAutoCache").toBool());
}
void ViewerOutput::ShiftVideoCache(const rational &from, const rational &to)
{
if (video_cache_enabled_) {
video_frame_cache_.Shift(from, to);
}
ShiftVideoEvent(from, to);
}
void ViewerOutput::ShiftAudioCache(const rational &from, const rational &to)
{
if (audio_cache_enabled_) {
audio_playback_cache_.Shift(from, to);
}
ShiftAudioEvent(from, to);
}
void ViewerOutput::ShiftCache(const rational &from, const rational &to)
{
ShiftVideoCache(from, to);
ShiftAudioCache(from, to);
}
void ViewerOutput::InvalidateCache(const TimeRange& range, const QString& from, int element, InvalidateCacheOptions options)
{
Q_UNUSED(element)
@@ -264,9 +238,9 @@ void ViewerOutput::InvalidateCache(const TimeRange& range, const QString& from,
if (invalidated_range.in() != invalidated_range.out()) {
if (from == kTextureInput || from == kVideoParamsInput) {
video_frame_cache_.Invalidate(invalidated_range);
video_frame_cache()->Invalidate(invalidated_range);
} else {
audio_playback_cache_.Invalidate(invalidated_range);
audio_playback_cache()->Invalidate(invalidated_range);
}
}
}
@@ -454,7 +428,7 @@ void ViewerOutput::InputValueChangedEvent(const QString &input, int element)
if (frame_rate_changed) {
if (video_cache_enabled_) {
video_frame_cache_.SetTimebase(new_video_params.frame_rate_as_time_base());
video_frame_cache()->SetTimebase(new_video_params.frame_rate_as_time_base());
}
emit FrameRateChanged(new_video_params.frame_rate());
}
@@ -476,7 +450,7 @@ void ViewerOutput::InputValueChangedEvent(const QString &input, int element)
emit AudioParamsChanged();
if (audio_cache_enabled_) {
audio_playback_cache_.SetParameters(GetAudioParams());
audio_playback_cache()->SetParameters(GetAudioParams());
}
cached_audio_params_ = new_audio_params;
@@ -487,18 +461,6 @@ void ViewerOutput::InputValueChangedEvent(const QString &input, int element)
super::InputValueChangedEvent(input, element);
}
void ViewerOutput::ShiftVideoEvent(const rational &from, const rational &to)
{
Q_UNUSED(from)
Q_UNUSED(to)
}
void ViewerOutput::ShiftAudioEvent(const rational &from, const rational &to)
{
Q_UNUSED(from)
Q_UNUSED(to)
}
void ViewerOutput::set_parameters_from_footage(const QVector<ViewerOutput *> footage)
{
foreach (ViewerOutput* f, footage) {
-22
View File
@@ -60,10 +60,6 @@ public:
void set_parameters_from_footage(const QVector<ViewerOutput *> footage);
void ShiftVideoCache(const rational& from, const rational& to);
void ShiftAudioCache(const rational& from, const rational& to);
void ShiftCache(const rational& from, const rational& to);
virtual void InvalidateCache(const TimeRange& range, const QString& from, int element, InvalidateCacheOptions options) override;
VideoParams GetVideoParams(int index = 0) const
@@ -146,16 +142,6 @@ public:
const rational &GetVideoLength() const { return video_length_; }
const rational &GetAudioLength() const { return audio_length_; }
FrameHashCache* video_frame_cache()
{
return &video_frame_cache_;
}
AudioPlaybackCache* audio_playback_cache()
{
return &audio_playback_cache_;
}
TimelinePoints* GetTimelinePoints()
{
return timeline_points_;
@@ -253,10 +239,6 @@ protected:
virtual rational VerifyLengthInternal(Track::Type type) const;
virtual void ShiftVideoEvent(const rational &from, const rational &to);
virtual void ShiftAudioEvent(const rational &from, const rational &to);
virtual void InputValueChangedEvent(const QString& input, int element) override;
int AddStream(Track::Type type, const QVariant &value);
@@ -266,10 +248,6 @@ private:
rational video_length_;
rational audio_length_;
FrameHashCache video_frame_cache_;
AudioPlaybackCache audio_playback_cache_;
VideoParams cached_video_params_;
AudioParams cached_audio_params_;
+4 -104
View File
@@ -170,108 +170,6 @@ void AudioPlaybackCache::WriteSilence(const TimeRange &range)
WritePCM(range, {range}, SampleBuffer());
}
void AudioPlaybackCache::ShiftEvent(const rational &from_in_time, const rational &to_in_time)
{
visual_.Shift(from_in_time, to_in_time);
qint64 to = params_.time_to_bytes_per_channel(to_in_time);
qint64 from = params_.time_to_bytes_per_channel(from_in_time);
if (from >= playlist_.GetLength()) {
return;
}
int to_seg_index = playlist_.GetIndexOfPosition(to);
int from_seg_index = playlist_.GetIndexOfPosition(from);
qint64 from_seg_start = playlist_.at(from_seg_index).offset();
qint64 from_seg_end = playlist_.at(from_seg_index).end();
if (from < to) {
// Shifting forwards, we must insert a new region and split a segment in half if necessary
int insert_index;
// Determine at what part of the array we'll be insert into
if (from == from_seg_start) {
insert_index = from_seg_index;
} else {
insert_index = from_seg_index + 1;
if (from < from_seg_end) {
// Split from segment into two
Segment second = CloneSegment(playlist_.at(from_seg_index));
TrimSegmentOut(&playlist_[from_seg_index], from - from_seg_start);
TrimSegmentIn(&second, from_seg_end - from);
playlist_.insert(insert_index, second);
}
}
// Insert silent segments
qint64 time_to_insert = to - from;
while (time_to_insert) {
qint64 new_seg_sz = qMin(kDefaultSegmentSizePerChannel, time_to_insert);
// Set offset to 0 for now and fill it in later
playlist_.insert(insert_index, CreateSegment(new_seg_sz, 0));
time_to_insert -= new_seg_sz;
}
UpdateOffsetsFrom(insert_index);
} else {
// Shifting backwards, we'll be removing segments and truncating them if necessary
qint64 to_seg_start = playlist_.at(to_seg_index).offset();
qint64 to_seg_end = playlist_.at(to_seg_index).end();
if (to_seg_index == from_seg_index) {
if (to > to_seg_start && from < from_seg_end) {
// Duplicate segment into two segments and trim each side to move the space in between
Segment second = CloneSegment(playlist_.at(to_seg_index));
from_seg_index++;
playlist_.insert(from_seg_index, second);
TrimSegmentOut(&playlist_[to_seg_index], to - to_seg_start);
TrimSegmentIn(&playlist_[from_seg_index], to_seg_end - from);
} else if (to == to_seg_start && from == from_seg_end) {
// Segment contains entire shift area, just remove it
RemoveSegmentFromArray(to_seg_index);
} else if (to == to_seg_start) {
// Trim segment in
TrimSegmentIn(&playlist_[to_seg_index], to_seg_end - from);
} else {
// Assume from == to_seg_end
TrimSegmentOut(&playlist_[to_seg_index], to_seg_end - to);
}
} else {
// Remove any segments between if there are any
while (from_seg_index != to_seg_index+1) {
RemoveSegmentFromArray(to_seg_index+1);
from_seg_index--;
}
if (from == from_seg_end) {
RemoveSegmentFromArray(from_seg_index);
} else {
// Assume from > from_seg_start and trim its in point
TrimSegmentIn(&playlist_[from_seg_index], from_seg_end - from);
}
if (to == to_seg_start) {
// Assume from >= to_seg_end, remove "to" segment
RemoveSegmentFromArray(to_seg_index);
} else {
TrimSegmentOut(&playlist_[to_seg_index], to_seg_end - to);
}
}
UpdateOffsetsFrom(to_seg_index);
}
}
AudioPlaybackCache::Segment AudioPlaybackCache::CloneSegment(const AudioPlaybackCache::Segment &s) const
{
Segment new_seg = s;
@@ -318,9 +216,11 @@ QString AudioPlaybackCache::GenerateSegmentFilename() const
{
QString new_seg_filename;
QDir cache_dir(QDir(GetCacheDirectory()).filePath(GetUuid().toString()));
do {
uint32_t r = QRandomGenerator::global()->generate();
new_seg_filename = QDir(GetCacheDirectory()).filePath(QStringLiteral("%1.pcm").arg(r));
new_seg_filename = cache_dir.filePath(QStringLiteral("%1.pcm").arg(r));
} while (QFileInfo::exists(new_seg_filename));
return new_seg_filename;
@@ -402,7 +302,7 @@ AudioPlaybackCache::PlaybackDevice *AudioPlaybackCache::CreatePlaybackDevice(QOb
PlaybackDevice *d = new PlaybackDevice(playlist_, params_.bytes_per_sample_per_channel(), parent);
// If we're child of a viewer, set the data limit so audio doesn't play beyond the length
if (ViewerOutput *viewer = viewer_parent()) {
if (ViewerOutput *viewer = dynamic_cast<ViewerOutput*>(this->parent())) {
d->SetDataLimit(params_.time_to_bytes_per_channel(viewer->GetAudioLength()));
}
-3
View File
@@ -208,9 +208,6 @@ public:
signals:
void ParametersChanged();
protected:
virtual void ShiftEvent(const rational& from, const rational& to) override;
private:
static const qint64 kDefaultSegmentSizePerChannel;
+5 -5
View File
@@ -67,7 +67,7 @@ void FrameHashCache::ValidateTime(const rational &time)
bool FrameHashCache::SaveCacheFrame(const int64_t &time, FramePtr frame) const
{
return SaveCacheFrame(GetCacheDirectory(), uuid_, time, frame);
return SaveCacheFrame(GetCacheDirectory(), GetUuid(), time, frame);
}
bool FrameHashCache::SaveCacheFrame(const QString &cache_path, const QUuid &uuid, const int64_t &time, FramePtr frame)
@@ -125,7 +125,7 @@ FramePtr FrameHashCache::LoadCacheFrame(const QString &cache_path, const QUuid &
FramePtr FrameHashCache::LoadCacheFrame(const int64_t &hash) const
{
return LoadCacheFrame(GetCacheDirectory(), uuid_, hash);
return LoadCacheFrame(GetCacheDirectory(), GetUuid(), hash);
}
FramePtr FrameHashCache::LoadCacheFrame(const QString &fn)
@@ -212,7 +212,7 @@ void FrameHashCache::HashDeleted(const QString& path, const QString &filename)
}
QFileInfo info(filename);
if (uuid_.toString() != info.dir().dirName()) {
if (GetUuid().toString() != info.dir().dirName()) {
return;
}
@@ -229,12 +229,12 @@ void FrameHashCache::ProjectInvalidated(Project *p)
QString FrameHashCache::CachePathName(const int64_t &time) const
{
return CachePathName(GetCacheDirectory(), uuid_, time);
return CachePathName(GetCacheDirectory(), GetUuid(), time);
}
QString FrameHashCache::CachePathName(const rational &time) const
{
return CachePathName(GetCacheDirectory(), uuid_, time, timebase_);
return CachePathName(GetCacheDirectory(), GetUuid(), time, timebase_);
}
QString FrameHashCache::CachePathName(const QString &cache_path, const QUuid &cache_id, const int64_t &time)
-8
View File
@@ -21,9 +21,6 @@
#ifndef VIDEORENDERFRAMECACHE_H
#define VIDEORENDERFRAMECACHE_H
#include <QMutex>
#include <QUuid>
#include "common/rational.h"
#include "common/timecodefunctions.h"
#include "common/timerange.h"
@@ -39,9 +36,6 @@ class FrameHashCache : public PlaybackCache
public:
FrameHashCache(QObject* parent = nullptr);
const QUuid &GetUuid() const { return uuid_; }
void SetUuid(const QUuid &u) { uuid_ = u; }
const rational &GetTimebase() const { return timebase_; }
void SetTimebase(const rational& tb);
@@ -86,8 +80,6 @@ private:
rational timebase_;
QUuid uuid_;
static const QString kCacheFormatExtension;
private slots:
+11 -38
View File
@@ -43,40 +43,16 @@ void PlaybackCache::Invalidate(const TimeRange &r, bool signal)
}
}
Node *PlaybackCache::parent() const
{
return dynamic_cast<Node*>(QObject::parent());
}
void PlaybackCache::InvalidateAll()
{
Invalidate(TimeRange(0, RATIONAL_MAX));
}
void PlaybackCache::Shift(rational from, rational to)
{
if (from == to) {
return;
}
// An region between `from` and `to` will be inserted or spliced out
TimeRangeList ranges_to_shift = validated_.Intersects(TimeRange(from, RATIONAL_MAX));
// Remove all ranges starting at to
validated_.remove(TimeRange(qMin(from, to), RATIONAL_MAX));
// Restore ranges shifted
rational diff = to - from;
foreach (const TimeRange& r, ranges_to_shift) {
validated_.insert(r + diff);
}
// Tell derivatives that a shift has occurred
ShiftEvent(from, to);
// Emit signals
emit Shifted(from, to);
if (diff > 0) {
//emit Invalidated(TimeRange(from, to));
}
}
void PlaybackCache::Validate(const TimeRange &r, bool signal)
{
validated_.insert(r);
@@ -90,15 +66,17 @@ void PlaybackCache::InvalidateEvent(const TimeRange &)
{
}
void PlaybackCache::ShiftEvent(const rational &, const rational &)
{
}
Project *PlaybackCache::GetProject() const
{
return Project::GetProjectFromObject(this);
}
PlaybackCache::PlaybackCache(QObject *parent) :
QObject(parent)
{
uuid_ = QUuid::createUuid();
}
TimeRangeList PlaybackCache::GetInvalidatedRanges(TimeRange intersecting)
{
TimeRangeList invalidated;
@@ -133,9 +111,4 @@ QString PlaybackCache::GetCacheDirectory() const
}
}
ViewerOutput *PlaybackCache::viewer_parent() const
{
return dynamic_cast<ViewerOutput*>(parent());
}
}
+10 -13
View File
@@ -21,14 +21,15 @@
#ifndef PLAYBACKCACHE_H
#define PLAYBACKCACHE_H
#include <QMutex>
#include <QObject>
#include <QUuid>
#include "common/jobtime.h"
#include "common/timerange.h"
namespace olive {
class Node;
class Project;
class ViewerOutput;
@@ -36,10 +37,10 @@ class PlaybackCache : public QObject
{
Q_OBJECT
public:
PlaybackCache(QObject* parent = nullptr) :
QObject(parent)
{
}
PlaybackCache(QObject* parent = nullptr);
const QUuid &GetUuid() const { return uuid_; }
void SetUuid(const QUuid &u) { uuid_ = u; }
TimeRangeList GetInvalidatedRanges(TimeRange intersecting);
TimeRangeList GetInvalidatedRanges(const rational &length)
@@ -55,36 +56,32 @@ public:
QString GetCacheDirectory() const;
ViewerOutput *viewer_parent() const;
void Invalidate(const TimeRange& r, bool signal = true);
const TimeRangeList &GetValidatedRanges() const { return validated_; }
Node *parent() const;
public slots:
void InvalidateAll();
void Shift(rational from, rational to);
signals:
void Invalidated(const olive::TimeRange& r);
void Validated(const olive::TimeRange& r);
void Shifted(const olive::rational& from, const olive::rational& to);
protected:
void Validate(const TimeRange& r, bool signal = true);
virtual void InvalidateEvent(const TimeRange& range);
virtual void ShiftEvent(const rational& from, const rational& to);
Project* GetProject() const;
private:
TimeRangeList validated_;
QUuid uuid_;
};
}
+4 -2
View File
@@ -557,7 +557,9 @@ RenderTicketWatcher* PreviewAutoCacher::RenderFrame(const rational& time, Render
watcher->setProperty("job", QVariant::fromValue(last_update_time_));
connect(watcher, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::VideoRendered);
video_tasks_.insert(watcher, time);
watcher->SetTicket(RenderManager::instance()->RenderFrame(copied_viewer_node_,
watcher->SetTicket(RenderManager::instance()->RenderFrame(copied_viewer_node_->GetConnectedTextureOutput(),
copied_viewer_node_->GetVideoParams(),
copied_viewer_node_->GetAudioParams(),
copied_color_manager_,
time,
RenderMode::kOffline,
@@ -574,7 +576,7 @@ RenderTicketPtr PreviewAutoCacher::RenderAudio(const TimeRange &r, bool generate
connect(watcher, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::AudioRendered);
audio_tasks_.insert(watcher, r);
RenderTicketPtr ticket = RenderManager::instance()->RenderAudio(copied_viewer_node_, r, RenderMode::kOffline, generate_waveforms, priority);
RenderTicketPtr ticket = RenderManager::instance()->RenderAudio(copied_viewer_node_->GetConnectedSampleOutput(), r, copied_viewer_node_->GetAudioParams(), RenderMode::kOffline, generate_waveforms, priority);
watcher->SetTicket(ticket);
return ticket;
}
+9 -14
View File
@@ -76,16 +76,16 @@ RenderManager::~RenderManager()
}
}
RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* color_manager,
const rational& time, RenderMode::Mode mode,
RenderTicketPtr RenderManager::RenderFrame(Node *node, const VideoParams &vparam, const AudioParams &param,
ColorManager* color_manager, const rational& time, RenderMode::Mode mode,
FrameHashCache* cache, RenderTicketPriority priority, ReturnType return_type)
{
return RenderFrame(viewer,
return RenderFrame(node,
color_manager,
time,
mode,
viewer->GetVideoParams(),
viewer->GetAudioParams(),
vparam,
param,
QSize(0, 0),
QMatrix4x4(),
VideoParams::kFormatInvalid,
@@ -95,7 +95,7 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* c
return_type);
}
RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* color_manager,
RenderTicketPtr RenderManager::RenderFrame(Node *node, ColorManager* color_manager,
const rational& time, RenderMode::Mode mode,
const VideoParams &video_params, const AudioParams &audio_params,
const QSize& force_size,
@@ -106,7 +106,7 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* c
// Create ticket
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
ticket->setProperty("viewer", Node::PtrToValue(viewer));
ticket->setProperty("node", Node::PtrToValue(node));
ticket->setProperty("time", QVariant::fromValue(time));
ticket->setProperty("size", force_size);
ticket->setProperty("matrix", force_matrix);
@@ -130,17 +130,12 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* c
return ticket;
}
RenderTicketPtr RenderManager::RenderAudio(ViewerOutput* viewer, const TimeRange& r, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority)
{
return RenderAudio(viewer, r, viewer->GetAudioParams(), mode, generate_waveforms, priority);
}
RenderTicketPtr RenderManager::RenderAudio(ViewerOutput* viewer, const TimeRange &r, const AudioParams &params, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority)
RenderTicketPtr RenderManager::RenderAudio(Node *node, const TimeRange &r, const AudioParams &params, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority)
{
// Create ticket
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
ticket->setProperty("viewer", Node::PtrToValue(viewer));
ticket->setProperty("node", Node::PtrToValue(node));
ticket->setProperty("time", QVariant::fromValue(r));
ticket->setProperty("type", kTypeAudio);
ticket->setProperty("mode", mode);
+3 -4
View File
@@ -76,10 +76,10 @@ public:
*
* This function is thread-safe.
*/
RenderTicketPtr RenderFrame(ViewerOutput *viewer, ColorManager* color_manager,
RenderTicketPtr RenderFrame(Node *node, const VideoParams &vparam, const AudioParams &param, ColorManager* color_manager,
const rational& time, RenderMode::Mode mode,
FrameHashCache* cache = nullptr, RenderTicketPriority priority = RenderTicketPriority::kNormal, ReturnType return_type = kFrame);
RenderTicketPtr RenderFrame(ViewerOutput* viewer, ColorManager* color_manager,
RenderTicketPtr RenderFrame(Node *node, ColorManager* color_manager,
const rational& time, RenderMode::Mode mode,
const VideoParams& video_params, const AudioParams& audio_params,
const QSize& force_size,
@@ -94,8 +94,7 @@ public:
*
* This function is thread-safe.
*/
RenderTicketPtr RenderAudio(ViewerOutput* viewer, const TimeRange& r, const AudioParams& params, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority = RenderTicketPriority::kNormal);
RenderTicketPtr RenderAudio(ViewerOutput *viewer, const TimeRange& r, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority = RenderTicketPriority::kNormal);
RenderTicketPtr RenderAudio(Node *viewer, const TimeRange& r, const AudioParams& params, RenderMode::Mode mode, bool generate_waveforms, RenderTicketPriority priority = RenderTicketPriority::kNormal);
virtual void RunTicket(RenderTicketPtr ticket) const override;
+4 -6
View File
@@ -46,13 +46,12 @@ RenderProcessor::RenderProcessor(RenderTicketPtr ticket, Renderer *render_ctx, D
TexturePtr RenderProcessor::GenerateTexture(const rational &time, const rational &frame_length)
{
ViewerOutput* viewer = Node::ValueToPtr<ViewerOutput>(ticket_->property("viewer"));
TimeRange range = TimeRange(time, time + frame_length);
NodeValueTable table;
if (Node *texture_output = viewer->GetConnectedTextureOutput()) {
table = GenerateTable(texture_output, range);
if (Node* node = Node::ValueToPtr<Node>(ticket_->property("node"))) {
table = GenerateTable(node, range);
}
NodeValue tex_val = table.Get(NodeValue::kTexture);
@@ -205,12 +204,11 @@ void RenderProcessor::Run()
}
case RenderManager::kTypeAudio:
{
ViewerOutput* viewer = Node::ValueToPtr<ViewerOutput>(ticket_->property("viewer"));
TimeRange time = ticket_->property("time").value<TimeRange>();
NodeValueTable table;
if (Node *texture_output = viewer->GetConnectedSampleOutput()) {
table = GenerateTable(texture_output, time);
if (Node* node = Node::ValueToPtr<Node>(ticket_->property("node"))) {
table = GenerateTable(node, time);
}
NodeValue sample_val = table.Get(NodeValue::kSamples);
+3 -4
View File
@@ -416,8 +416,7 @@ void TimelineWidget::SplitAtPlayhead()
void TimelineWidget::ReplaceBlocksWithGaps(const QVector<Block *> &blocks,
bool remove_from_graph,
MultiUndoCommand *command,
bool handle_transitions,
bool handle_invalidations)
bool handle_transitions)
{
foreach (Block* b, blocks) {
if (dynamic_cast<GapBlock*>(b)) {
@@ -428,7 +427,7 @@ void TimelineWidget::ReplaceBlocksWithGaps(const QVector<Block *> &blocks,
Track* original_track = b->track();
command->add_child(new TrackReplaceBlockWithGapCommand(original_track, b, handle_transitions, handle_invalidations));
command->add_child(new TrackReplaceBlockWithGapCommand(original_track, b, handle_transitions));
if (remove_from_graph) {
command->add_child(new NodeRemoveWithExclusiveDependenciesAndDisconnect(b));
@@ -482,7 +481,7 @@ void TimelineWidget::DeleteSelected(bool ripple)
}
// Replace clips with gaps (effectively deleting them)
ReplaceBlocksWithGaps(clips_to_delete, true, command, false, !ripple);
ReplaceBlocksWithGaps(clips_to_delete, true, command, false);
// Insert ripple command now that it's all cleaned up gaps
TimelineRippleDeleteGapsAtRegionsCommand *ripple_command = nullptr;
+1 -1
View File
@@ -126,7 +126,7 @@ public:
void RestoreSplitterState(const QByteArray& state);
static void ReplaceBlocksWithGaps(const QVector<Block *> &blocks, bool remove_from_graph, MultiUndoCommand *command, bool handle_transitions = true, bool handle_invalidations = true);
static void ReplaceBlocksWithGaps(const QVector<Block *> &blocks, bool remove_from_graph, MultiUndoCommand *command, bool handle_transitions = true);
/**
* @brief Retrieve the QGraphicsItem at a particular scene position
@@ -208,8 +208,6 @@ void TransitionRemoveCommand::redo()
Q_ASSERT(out_block_ || in_block_);
track_->BeginOperation();
TimeRange invalidate_range(block_->in(), block_->out());
if (in_block_) {
@@ -230,10 +228,6 @@ void TransitionRemoveCommand::redo()
track_->RippleRemoveBlock(block_);
track_->EndOperation();
track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput);
if (remove_from_graph_) {
if (!remove_command_) {
remove_command_ = CreateRemoveCommand(block_);
@@ -249,8 +243,6 @@ void TransitionRemoveCommand::undo()
remove_command_->undo_now();
}
track_->BeginOperation();
if (in_block_) {
track_->InsertBlockBefore(block_, in_block_);
} else {
@@ -275,10 +267,6 @@ void TransitionRemoveCommand::undo()
if (out_block_) {
out_block_->set_length_and_media_out(out_block_->length() - block_->out_offset());
}
track_->EndOperation();
track_->Node::InvalidateCache(TimeRange(block_->in(), block_->out()), Track::kBlockInput);
}
//
@@ -287,11 +275,8 @@ void TransitionRemoveCommand::undo()
void TrackListInsertGaps::prepare()
{
// Determine if all tracks will be affected, which will allow us to make some optimizations
all_tracks_unlocked_ = true;
foreach (Track* track, track_list_->GetTracks()) {
if (track->IsLocked()) {
all_tracks_unlocked_ = false;
continue;
}
@@ -346,19 +331,6 @@ void TrackListInsertGaps::prepare()
void TrackListInsertGaps::redo()
{
if (all_tracks_unlocked_) {
// Optimize by shifting over since we have a constant amount of time being inserted
if (track_list_->type() == Track::kVideo) {
track_list_->parent()->ShiftVideoCache(point_, point_ + length_);
} else if (track_list_->type() == Track::kAudio) {
track_list_->parent()->ShiftAudioCache(point_, point_ + length_);
}
}
foreach (Track* track, working_tracks_) {
track->BeginOperation();
}
foreach (Block* gap, gaps_to_extend_) {
gap->set_length_and_media_out(gap->length() + length_);
}
@@ -371,33 +343,10 @@ void TrackListInsertGaps::redo()
add_gap.gap->setParent(add_gap.track->parent());
add_gap.track->InsertBlockAfter(add_gap.gap, add_gap.before);
}
foreach (Track* track, working_tracks_) {
track->EndOperation();
}
if (!all_tracks_unlocked_) {
foreach (Track* track, working_tracks_) {
track->Node::InvalidateCache(TimeRange(point_, RATIONAL_MAX), Track::kBlockInput);
}
}
}
void TrackListInsertGaps::undo()
{
if (all_tracks_unlocked_) {
// Optimize by shifting over since we have a constant amount of time being inserted
if (track_list_->type() == Track::kVideo) {
track_list_->parent()->ShiftVideoCache(point_ + length_, point_);
} else if (track_list_->type() == Track::kAudio) {
track_list_->parent()->ShiftAudioCache(point_ + length_, point_);
}
}
foreach (Track* track, working_tracks_) {
track->BeginOperation();
}
// Remove added gaps
foreach (auto add_gap, gaps_added_) {
add_gap.gap->track()->RippleRemoveBlock(add_gap.gap);
@@ -413,16 +362,6 @@ void TrackListInsertGaps::undo()
foreach (Block* gap, gaps_to_extend_) {
gap->set_length_and_media_out(gap->length() - length_);
}
foreach (Track* track, working_tracks_) {
track->EndOperation();
}
if (!all_tracks_unlocked_) {
foreach (Track* track, working_tracks_) {
track->Node::InvalidateCache(TimeRange(point_, RATIONAL_MAX), Track::kBlockInput);
}
}
}
//
@@ -440,8 +379,6 @@ void TrackReplaceBlockWithGapCommand::redo()
}
if (block_->next()) {
track_->BeginOperation();
// Invalidate the range inhabited by this block
TimeRange invalidate_range(block_->in(), block_->out());
@@ -488,12 +425,6 @@ void TrackReplaceBlockWithGapCommand::redo()
track_->ReplaceBlock(block_, our_gap_);
}
track_->EndOperation();
if (handle_invalidations_) {
track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput);
}
} else {
// Block is at the end of the track, simply remove it
Block* preceding = block_->previous();
@@ -512,8 +443,6 @@ void TrackReplaceBlockWithGapCommand::redo()
void TrackReplaceBlockWithGapCommand::undo()
{
if (our_gap_ || existing_gap_) {
track_->BeginOperation();
if (our_gap_) {
// We made this gap, simply swap our gap back
@@ -547,11 +476,6 @@ void TrackReplaceBlockWithGapCommand::undo()
}
track_->EndOperation();
if (handle_invalidations_) {
track_->Node::InvalidateCache(TimeRange(block_->in(), block_->out()), Track::kBlockInput);
}
} else {
// Our gap and existing gap were both null, our block must have been at the end and thus
@@ -233,14 +233,13 @@ private:
class TrackReplaceBlockWithGapCommand : public UndoCommand {
public:
TrackReplaceBlockWithGapCommand(Track* track, Block* block, bool handle_transitions = true, bool handle_invalidations = true) :
TrackReplaceBlockWithGapCommand(Track* track, Block* block, bool handle_transitions = true) :
track_(track),
block_(block),
existing_gap_(nullptr),
existing_merged_gap_(nullptr),
our_gap_(nullptr),
handle_transitions_(handle_transitions),
handle_invalidations_(handle_invalidations)
handle_transitions_(handle_transitions)
{
}
@@ -266,7 +265,6 @@ private:
GapBlock* our_gap_;
bool handle_transitions_;
bool handle_invalidations_;
QObject memory_manager_;
@@ -344,8 +342,6 @@ private:
QVector<Track*> working_tracks_;
bool all_tracks_unlocked_;
QVector<Block*> gaps_to_extend_;
struct AddGap {
@@ -362,62 +358,6 @@ private:
};
class NodeBeginOperationCommand : public UndoCommand
{
public:
NodeBeginOperationCommand(Node *node) :
node_(node)
{}
virtual Project* GetRelevantProject() const override
{
return node_->project();
}
protected:
virtual void redo() override
{
node_->BeginOperation();
}
virtual void undo() override
{
node_->EndOperation();
}
private:
Node *node_;
};
class NodeEndOperationCommand : public UndoCommand
{
public:
NodeEndOperationCommand(Node *node) :
node_(node)
{}
virtual Project* GetRelevantProject() const override
{
return node_->project();
}
protected:
virtual void redo() override
{
node_->EndOperation();
}
virtual void undo() override
{
node_->BeginOperation();
}
private:
Node *node_;
};
}
#endif // TIMELINEUNDOGENERAL_H
@@ -36,9 +36,6 @@ void BlockTrimCommand::redo()
return;
}
// Begin an operation since we'll be doing a lot
track_->BeginOperation();
// Determine how much time to invalidate
TimeRange invalidate_range;
@@ -82,14 +79,10 @@ void BlockTrimCommand::redo()
}
}
track_->EndOperation();
if (dynamic_cast<TransitionBlock*>(block_)) {
// Whole transition needs to be invalidated
invalidate_range = block_->range();
}
track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput);
}
void BlockTrimCommand::undo()
@@ -98,8 +91,6 @@ void BlockTrimCommand::undo()
return;
}
track_->BeginOperation();
// Will be POSITIVE if trimming shorter and NEGATIVE if trimming longer
if (needs_adjacent_) {
if (we_created_adjacent_) {
@@ -146,10 +137,6 @@ void BlockTrimCommand::undo()
// Whole transition needs to be invalidated
invalidate_range = block_->range();
}
track_->EndOperation();
track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput);
}
void BlockTrimCommand::prepare()
@@ -200,8 +187,6 @@ void TrackSlideCommand::redo()
// Make sure all movement blocks' old positions are invalidated
TimeRange invalidate_range(blocks_.first()->in(), blocks_.last()->out());
track_->BeginOperation();
// We will always have an in adjacent if there was a valid slide
if (we_created_in_adjacent_) {
// We created in adjacent, so all we have to do is insert it
@@ -246,13 +231,9 @@ void TrackSlideCommand::redo()
}
}
track_->EndOperation();
// Make sure all movement blocks' new positions are invalidated
invalidate_range.set_range(qMin(invalidate_range.in(), blocks_.first()->in()),
qMax(invalidate_range.out(), blocks_.last()->out()));
track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput);
}
@@ -261,8 +242,6 @@ void TrackSlideCommand::undo()
// Make sure all movement blocks' old positions are invalidated
TimeRange invalidate_range(blocks_.first()->in(), blocks_.last()->out());
track_->BeginOperation();
if (we_created_in_adjacent_) {
// We created this, so we can remove it now
track_->RippleRemoveBlock(in_adjacent_);
@@ -287,13 +266,9 @@ void TrackSlideCommand::undo()
}
}
track_->EndOperation();
// Make sure all movement blocks' new positions are invalidated
invalidate_range.set_range(qMin(invalidate_range.in(), blocks_.first()->in()),
qMax(invalidate_range.out(), blocks_.last()->out()));
track_->Node::InvalidateCache(invalidate_range, Track::kBlockInput);
}
void TrackSlideCommand::prepare()
@@ -328,8 +303,6 @@ TrackPlaceBlockCommand::~TrackPlaceBlockCommand()
void TrackPlaceBlockCommand::redo()
{
TimeRangeList ranges_to_invalidate;
// Determine if we need to add tracks
if (track_index_ >= timeline_->GetTracks().size()) {
if (add_track_commands_.isEmpty()) {
@@ -348,8 +321,6 @@ void TrackPlaceBlockCommand::redo()
Track* track = timeline_->GetTrackAt(track_index_);
track->BeginOperation();
bool append = (in_ >= track->track_length());
// Check if the placement location is past the end of the timeline
@@ -362,7 +333,6 @@ void TrackPlaceBlockCommand::redo()
}
gap_->setParent(track->parent());
track->AppendBlock(gap_);
ranges_to_invalidate.insert(gap_->range());
}
track->AppendBlock(insert_);
@@ -376,14 +346,6 @@ void TrackPlaceBlockCommand::redo()
ripple_remove_command_->redo_now();
track->InsertBlockAfter(insert_, ripple_remove_command_->GetInsertionIndex());
}
track->EndOperation();
ranges_to_invalidate.insert(insert_->range());
foreach (const TimeRange &r, ranges_to_invalidate) {
track->Node::InvalidateCache(r, Track::kBlockInput);
}
}
void TrackPlaceBlockCommand::undo()
@@ -393,7 +355,6 @@ void TrackPlaceBlockCommand::undo()
TimeRange insert_range(insert_->in(), insert_->out());
// Firstly, remove our insert
t->BeginOperation();
t->RippleRemoveBlock(insert_);
if (ripple_remove_command_) {
@@ -403,9 +364,6 @@ void TrackPlaceBlockCommand::undo()
t->RippleRemoveBlock(gap_);
gap_->setParent(&memory_manager_);
}
t->EndOperation();
t->Node::InvalidateCache(insert_range, Track::kBlockInput);
// Remove tracks if we added them
for (int i=add_track_commands_.size()-1; i>=0; i--) {
@@ -106,8 +106,6 @@ void TrackRippleRemoveAreaCommand::prepare()
void TrackRippleRemoveAreaCommand::redo()
{
track_->BeginOperation();
if (splice_split_command_) {
// We're just splicing
splice_split_command_->redo_now();
@@ -145,17 +143,10 @@ void TrackRippleRemoveAreaCommand::redo()
}
}
}
track_->EndOperation();
track_->Node::InvalidateCache(TimeRange(range_.in(), RATIONAL_MAX), Track::kBlockInput);
}
void TrackRippleRemoveAreaCommand::undo()
{
// Begin operations
track_->BeginOperation();
if (splice_split_command_) {
splice_split_command_->undo_now();
} else {
@@ -176,85 +167,36 @@ void TrackRippleRemoveAreaCommand::undo()
track_->InsertBlockAfter(op.block, op.before);
}
}
// End operations and invalidate
track_->EndOperation();
track_->Node::InvalidateCache(TimeRange(range_.in(), RATIONAL_MAX), Track::kBlockInput);
}
//
// TrackListRippleRemoveAreaCommand
//
void TrackListRippleRemoveAreaCommand::prepare()
{
foreach (Track* track, list_->GetTracks()) {
if (track->IsLocked()) {
continue;
}
TrackRippleRemoveAreaCommand* c = new TrackRippleRemoveAreaCommand(track, range_);
commands_.append(c);
working_tracks_.append(track);
}
}
void TrackListRippleRemoveAreaCommand::redo()
{
// Code that's only run on the first redo
if (commands_.isEmpty()) {
all_tracks_unlocked_ = true;
foreach (Track* track, list_->GetTracks()) {
if (track->IsLocked()) {
all_tracks_unlocked_ = false;
continue;
}
TrackRippleRemoveAreaCommand* c = new TrackRippleRemoveAreaCommand(track, range_);
commands_.append(c);
working_tracks_.append(track);
}
}
if (all_tracks_unlocked_) {
// We can optimize here by simply shifting the whole cache forward instead of re-caching
// everything following this time
if (list_->type() == Track::kVideo) {
list_->parent()->ShiftVideoCache(range_.out(), range_.in());
} else if (list_->type() == Track::kAudio) {
list_->parent()->ShiftAudioCache(range_.out(), range_.in());
}
foreach (Track* track, working_tracks_) {
track->BeginOperation();
}
}
foreach (TrackRippleRemoveAreaCommand* c, commands_) {
c->redo_now();
}
if (all_tracks_unlocked_) {
foreach (Track* track, working_tracks_) {
track->EndOperation();
}
}
}
void TrackListRippleRemoveAreaCommand::undo()
{
if (all_tracks_unlocked_) {
// We can optimize here by simply shifting the whole cache forward instead of re-caching
// everything following this time
if (list_->type() == Track::kVideo) {
list_->parent()->ShiftVideoCache(range_.in(), range_.out());
} else if (list_->type() == Track::kAudio) {
list_->parent()->ShiftAudioCache(range_.in(), range_.out());
}
foreach (Track* track, working_tracks_) {
track->BeginOperation();
}
}
foreach (TrackRippleRemoveAreaCommand* c, commands_) {
c->undo_now();
}
if (all_tracks_unlocked_) {
foreach (Track* track, working_tracks_) {
track->EndOperation();
track->Node::InvalidateCache(range_, Track::kBlockInput);
}
}
}
//
@@ -282,7 +224,6 @@ TrackListRippleToolCommand::TrackListRippleToolCommand(TrackList* track_list,
ripple_movement_(ripple_movement),
movement_mode_(movement_mode)
{
all_tracks_unlocked_ = (info_.size() == track_list_->GetTrackCount());
}
void TrackListRippleToolCommand::ripple(bool redo)
@@ -324,9 +265,6 @@ void TrackListRippleToolCommand::ripple(bool redo)
rational pre_shift;
rational post_shift;
// Begin operation so we can invalidate better later
track->BeginOperation();
if (info.append_gap) {
// Rather than rippling the referenced block, we'll insert a gap and ripple with that
@@ -429,29 +367,6 @@ void TrackListRippleToolCommand::ripple(bool redo)
pre_latest_out = qMax(pre_latest_out, pre_shift);
post_latest_out = qMax(post_latest_out, post_shift);
}
if (all_tracks_unlocked_) {
// We rippled all the tracks, so we can shift the whole cache
if (track_list_->type() == Track::kVideo) {
track_list_->parent()->ShiftVideoCache(pre_latest_out, post_latest_out);
} else if (track_list_->type() == Track::kAudio) {
track_list_->parent()->ShiftAudioCache(pre_latest_out, post_latest_out);
}
}
for (auto it=working_data_.cbegin(); it!=working_data_.cend(); it++) {
Track* track = it.key();
track->EndOperation();
if (!all_tracks_unlocked_) {
// If we're not shifting, the whole track must get invalidated
track->Node::InvalidateCache(TimeRange(it.value().earliest_point_of_change, RATIONAL_MAX), Track::kBlockInput);
} else if (pre_latest_out < post_latest_out) {
// If we're here, then a new section has been rippled in that needs to be rendered
track->Node::InvalidateCache(TimeRange(pre_latest_out, post_latest_out), Track::kBlockInput);
}
}
}
//
@@ -513,11 +428,8 @@ void TimelineRippleDeleteGapsAtRegionsCommand::prepare()
// Determine which gaps will be involved in this operation
QVector<GapBlock*> gaps;
bool all_tracks_unlocked = true;
foreach (Track* track, timeline_->GetTracks()) {
if (track->IsLocked()) {
all_tracks_unlocked = false;
continue;
}
@@ -573,24 +485,12 @@ void TimelineRippleDeleteGapsAtRegionsCommand::prepare()
if (ripple_length > 0) {
foreach (GapBlock *gap, gaps) {
if (all_tracks_unlocked) {
commands_.append(new NodeBeginOperationCommand(gap->track()));
}
if (gap_lengths.value(gap) == ripple_length) {
commands_.append(new TrackRippleRemoveBlockCommand(gap->track(), gap));
} else {
gap_lengths[gap] -= ripple_length;
commands_.append(new BlockResizeCommand(gap, gap_lengths.value(gap)));
}
if (all_tracks_unlocked) {
commands_.append(new NodeEndOperationCommand(gap->track()));
}
}
if (all_tracks_unlocked) {
commands_.append(new TimelineShiftCacheCommand(timeline_, latest_point, latest_point - ripple_length));
}
}
}
@@ -610,14 +510,4 @@ void TimelineRippleDeleteGapsAtRegionsCommand::undo()
}
}
void TimelineShiftCacheCommand::redo()
{
timeline_->ShiftCache(from_, to_);
}
void TimelineShiftCacheCommand::undo()
{
timeline_->ShiftCache(to_, from_);
}
}
@@ -119,6 +119,8 @@ public:
}
protected:
virtual void prepare() override;
virtual void redo() override;
virtual void undo() override;
@@ -130,8 +132,6 @@ private:
TimeRange range_;
bool all_tracks_unlocked_;
QVector<TrackRippleRemoveAreaCommand*> commands_;
};
@@ -200,8 +200,6 @@ private:
QObject memory_manager_;
bool all_tracks_unlocked_;
};
class TimelineRippleDeleteGapsAtRegionsCommand : public UndoCommand
@@ -250,34 +248,6 @@ private:
};
class TimelineShiftCacheCommand : public UndoCommand
{
public:
TimelineShiftCacheCommand(Sequence* timeline, const rational &from, const rational &to) :
timeline_(timeline),
from_(from),
to_(to)
{}
virtual Project* GetRelevantProject() const override
{
return timeline_->project();
}
protected:
virtual void redo() override;
virtual void undo() override;
private:
Sequence* timeline_;
rational from_;
rational to_;
};
}
#endif // TIMELINEUNDORIPPLE_H
@@ -53,7 +53,6 @@ void BlockSplitCommand::redo()
// Begin an operation
Track* track = block_->track();
track->BeginOperation();
// Set lengths
block_->set_length_and_media_out(new_length);
@@ -76,16 +75,12 @@ void BlockSplitCommand::redo()
}
}
}
track->EndOperation();
}
void BlockSplitCommand::undo()
{
Track* track = block_->track();
track->BeginOperation();
if (moved_transition_.IsValid()) {
Node::DisconnectEdge(new_block(), moved_transition_);
Node::ConnectEdge(block_, moved_transition_);
@@ -96,8 +91,6 @@ void BlockSplitCommand::undo()
// If we ran a reconnect command, disconnect now
reconnect_tree_command_->undo_now();
track->EndOperation();
}
//
+26 -26
View File
@@ -82,7 +82,6 @@ void TimeRuler::SetPlaybackCache(PlaybackCache *cache)
if (playback_cache_) {
disconnect(playback_cache_, &PlaybackCache::Invalidated, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
disconnect(playback_cache_, &PlaybackCache::Validated, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
disconnect(playback_cache_, &PlaybackCache::Shifted, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
}
playback_cache_ = cache;
@@ -90,7 +89,6 @@ void TimeRuler::SetPlaybackCache(PlaybackCache *cache)
if (playback_cache_) {
connect(playback_cache_, &PlaybackCache::Invalidated, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
connect(playback_cache_, &PlaybackCache::Validated, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
connect(playback_cache_, &PlaybackCache::Shifted, viewport(), static_cast<void(QWidget::*)()>(&QWidget::update));
}
update();
@@ -257,35 +255,37 @@ void TimeRuler::drawForeground(QPainter *p, const QRectF &rect)
// If cache status is enabled
if (show_cache_status_ && playback_cache_) {
// FIXME: Hardcoded to get video length, if we ever need audio length, this will have to change
rational len = playback_cache_->viewer_parent()->GetVideoLength();
int lim_left = GetScroll();
int lim_right = lim_left + width();
if (ViewerOutput *viewer = dynamic_cast<ViewerOutput*>(playback_cache_->parent())) {
rational len = viewer->GetVideoLength();
int lim_left = GetScroll();
int lim_right = lim_left + width();
int cache_screen_length = TimeToScene(len);
int cache_screen_length = TimeToScene(len);
if (cache_screen_length > 0) {
int cache_y = height() - cache_status_height_;
if (cache_screen_length > 0) {
int cache_y = height() - cache_status_height_;
p->fillRect(0, cache_y, cache_screen_length, cache_status_height_, Qt::green);
p->fillRect(0, cache_y, cache_screen_length, cache_status_height_, Qt::green);
foreach (const TimeRange& range, playback_cache_->GetInvalidatedRanges(len)) {
int range_left = TimeToScene(range.in());
if (range_left >= width()) {
continue;
foreach (const TimeRange& range, playback_cache_->GetInvalidatedRanges(len)) {
int range_left = TimeToScene(range.in());
if (range_left >= width()) {
continue;
}
int range_right = TimeToScene(range.out());
if (range_right < 0) {
continue;
}
int adjusted_left = qMax(lim_left, range_left);
p->fillRect(adjusted_left,
cache_y,
qMin(lim_right, range_right) - adjusted_left,
cache_status_height_,
Qt::red);
}
int range_right = TimeToScene(range.out());
if (range_right < 0) {
continue;
}
int adjusted_left = qMax(lim_left, range_left);
p->fillRect(adjusted_left,
cache_y,
qMin(lim_right, range_right) - adjusted_left,
cache_status_height_,
Qt::red);
}
}
}
-9
View File
@@ -205,7 +205,6 @@ void ViewerWidget::ConnectNodeEvent(ViewerOutput *n)
connect(n, &ViewerOutput::VideoParamsChanged, this, &ViewerWidget::UpdateRendererVideoParameters);
connect(n, &ViewerOutput::AudioParamsChanged, this, &ViewerWidget::UpdateRendererAudioParameters);
connect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange);
connect(n->video_frame_cache(), &FrameHashCache::Shifted, this, &ViewerWidget::ViewerShiftedRange);
connect(n, &ViewerOutput::TextureInputChanged, this, &ViewerWidget::UpdateStack);
VideoParams vp = n->GetVideoParams();
@@ -250,7 +249,6 @@ void ViewerWidget::DisconnectNodeEvent(ViewerOutput *n)
disconnect(n, &ViewerOutput::VideoParamsChanged, this, &ViewerWidget::UpdateRendererVideoParameters);
disconnect(n, &ViewerOutput::AudioParamsChanged, this, &ViewerWidget::UpdateRendererAudioParameters);
disconnect(n->video_frame_cache(), &FrameHashCache::Invalidated, this, &ViewerWidget::ViewerInvalidatedVideoRange);
disconnect(n->video_frame_cache(), &FrameHashCache::Shifted, this, &ViewerWidget::ViewerShiftedRange);
disconnect(n, &ViewerOutput::TextureInputChanged, this, &ViewerWidget::UpdateStack);
CloseAudioProcessor();
@@ -1556,13 +1554,6 @@ void ViewerWidget::ManualSwitchToWaveform(bool e)
}
}
void ViewerWidget::ViewerShiftedRange(const rational &from, const rational &to)
{
if (GetTime() >= qMin(from, to)) {
QMetaObject::invokeMethod(this, &ViewerWidget::UpdateTextureFromNode, Qt::QueuedConnection);
}
}
void ViewerWidget::DragEntered(QDragEnterEvent* event)
{
if (event->mimeData()->formats().contains(Project::kItemMimeType)) {
-2
View File
@@ -291,8 +291,6 @@ private slots:
void SetZoomFromMenu(QAction* action);
void ViewerShiftedRange(const olive::rational& from, const olive::rational& to);
void UpdateStack();
void ContextMenuSetFullScreen(QAction* action);