refactored so sequence is again a derivative of viewer

This commit is contained in:
itsmattkc
2021-04-05 14:41:59 +10:00
parent 748f45b7b8
commit 9be014c0b6
38 changed files with 600 additions and 565 deletions
+9 -6
View File
@@ -342,10 +342,11 @@ void Core::DialogPreferencesShow()
void Core::DialogExportShow()
{
Sequence* viewer = GetSequenceToExport();
ViewerOutput* viewer;
TimelinePoints* points;
if (viewer) {
ExportDialog* ed = new ExportDialog(viewer, main_window_);
if (GetSequenceToExport(&viewer, &points) && viewer) {
ExportDialog* ed = new ExportDialog(viewer, points, main_window_);
connect(ed, &ExportDialog::finished, ed, &ExportDialog::deleteLater);
ed->open();
}
@@ -751,7 +752,7 @@ void Core::SaveProjectInternal(Project* project, const QString& override_filenam
task_dialog->open();
}
Sequence *Core::GetSequenceToExport()
bool Core::GetSequenceToExport(ViewerOutput** viewer, TimelinePoints** points)
{
// First try the most recently focused time based window
TimeBasedPanel* time_panel = PanelManager::instance()->MostRecentlyFocused<TimeBasedPanel>();
@@ -769,7 +770,9 @@ Sequence *Core::GetSequenceToExport()
tr("This Sequence is empty. There is nothing to export."),
QMessageBox::Ok);
} else {
return time_panel->GetConnectedViewer();
*viewer = time_panel->GetConnectedViewer();
*points = time_panel->GetConnectedTimelinePoints();
return true;
}
} else {
QMessageBox::critical(main_window_,
@@ -778,7 +781,7 @@ Sequence *Core::GetSequenceToExport()
QMessageBox::Ok);
}
return nullptr;
return false;
}
QString Core::GetAutoRecoveryIndexFilename()
+1 -1
View File
@@ -496,7 +496,7 @@ private:
/**
* @brief Retrieves the currently most active sequence for exporting
*/
Sequence* GetSequenceToExport();
bool GetSequenceToExport(ViewerOutput **viewer, TimelinePoints **points);
static QString GetAutoRecoveryIndexFilename();
+27 -25
View File
@@ -39,9 +39,10 @@
namespace olive {
ExportDialog::ExportDialog(Sequence *sequence, QWidget *parent) :
ExportDialog::ExportDialog(ViewerOutput *viewer_node, TimelinePoints *points, QWidget *parent) :
QDialog(parent),
sequence_(sequence)
viewer_node_(viewer_node),
timeline_points_(points)
{
QHBoxLayout* layout = new QHBoxLayout(this);
@@ -104,7 +105,7 @@ ExportDialog::ExportDialog(Sequence *sequence, QWidget *parent) :
range_combobox_ = new QComboBox();
range_combobox_->addItem(tr("Entire Sequence"));
range_combobox_->addItem(tr("In to Out"));
range_combobox_->setEnabled(sequence_->timeline_points()->workarea()->enabled());
range_combobox_->setEnabled(timeline_points_ && timeline_points_->workarea()->enabled());
preferences_layout->addWidget(range_combobox_, row, 1, 1, 3);
@@ -136,7 +137,7 @@ ExportDialog::ExportDialog(Sequence *sequence, QWidget *parent) :
QTabWidget* preferences_tabs = new QTabWidget();
QScrollArea* video_area = new QScrollArea();
color_manager_ = sequence_->project()->color_manager();
color_manager_ = viewer_node_->project()->color_manager();
video_tab_ = new ExportVideoTab(color_manager_);
video_area->setWidgetResizable(true);
video_area->setWidget(video_tab_);
@@ -188,18 +189,18 @@ ExportDialog::ExportDialog(Sequence *sequence, QWidget *parent) :
&ExportDialog::FormatChanged);
FormatChanged(ExportFormat::kFormatMPEG4);
video_tab_->width_slider()->SetValue(sequence_->video_params().width());
video_tab_->width_slider()->SetDefaultValue(sequence_->video_params().width());
video_tab_->height_slider()->SetValue(sequence_->video_params().height());
video_tab_->height_slider()->SetDefaultValue(sequence_->video_params().height());
video_tab_->frame_rate_combobox()->SetFrameRate(sequence_->video_params().time_base().flipped());
video_tab_->pixel_aspect_combobox()->SetPixelAspectRatio(sequence_->video_params().pixel_aspect_ratio());
video_tab_->width_slider()->SetValue(viewer_node_->video_params().width());
video_tab_->width_slider()->SetDefaultValue(viewer_node_->video_params().width());
video_tab_->height_slider()->SetValue(viewer_node_->video_params().height());
video_tab_->height_slider()->SetDefaultValue(viewer_node_->video_params().height());
video_tab_->frame_rate_combobox()->SetFrameRate(viewer_node_->video_params().time_base().flipped());
video_tab_->pixel_aspect_combobox()->SetPixelAspectRatio(viewer_node_->video_params().pixel_aspect_ratio());
video_tab_->pixel_format_field()->SetPixelFormat(static_cast<VideoParams::Format>(Config::Current()["OnlinePixelFormat"].toInt()));
video_tab_->interlaced_combobox()->SetInterlaceMode(sequence_->video_params().interlacing());
audio_tab_->sample_rate_combobox()->SetSampleRate(sequence_->audio_params().sample_rate());
audio_tab_->channel_layout_combobox()->SetChannelLayout(sequence_->audio_params().channel_layout());
video_tab_->interlaced_combobox()->SetInterlaceMode(viewer_node_->video_params().interlacing());
audio_tab_->sample_rate_combobox()->SetSampleRate(viewer_node_->audio_params().sample_rate());
audio_tab_->channel_layout_combobox()->SetChannelLayout(viewer_node_->audio_params().channel_layout());
video_aspect_ratio_ = static_cast<double>(sequence_->video_params().width()) / static_cast<double>(sequence_->video_params().height());
video_aspect_ratio_ = static_cast<double>(viewer_node_->video_params().width()) / static_cast<double>(viewer_node_->video_params().height());
connect(video_tab_->width_slider(),
&IntegerSlider::ValueChanged,
@@ -227,8 +228,8 @@ ExportDialog::ExportDialog(Sequence *sequence, QWidget *parent) :
static_cast<void(ViewerWidget::*)(const ColorTransform&)>(&ViewerWidget::SetColorTransform));
// Set viewer to view the node
preview_viewer_->ConnectViewerNode(sequence_);
preview_viewer_->ruler()->ConnectTimelinePoints(sequence_->timeline_points());
preview_viewer_->ConnectViewerNode(viewer_node_);
preview_viewer_->ruler()->ConnectTimelinePoints(timeline_points_);
preview_viewer_->SetColorMenuEnabled(false);
preview_viewer_->SetColorTransform(video_tab_->CurrentOCIOColorSpace());
}
@@ -315,7 +316,7 @@ void ExportDialog::StartExport()
return;
}
ExportTask* task = new ExportTask(sequence_, color_manager_, GenerateParams());
ExportTask* task = new ExportTask(viewer_node_, color_manager_, GenerateParams());
TaskDialog* td = new TaskDialog(task, tr("Export"), this);
connect(td, &TaskDialog::TaskSucceeded, this, &ExportDialog::ExportFinished);
td->open();
@@ -428,7 +429,7 @@ void ExportDialog::LoadPresets()
void ExportDialog::SetDefaultFilename()
{
Project* p = sequence_->project();
Project* p = viewer_node_->project();
QDir doc_location;
@@ -438,7 +439,7 @@ void ExportDialog::SetDefaultFilename()
doc_location = QFileInfo(p->filename()).dir();
}
QString file_location = doc_location.filePath(sequence_->GetLabel());
QString file_location = doc_location.filePath(viewer_node_->GetLabel());
filename_edit_->setText(file_location);
}
@@ -459,11 +460,12 @@ ExportParams ExportDialog::GenerateParams() const
ExportParams params;
params.SetFilename(filename_edit_->text().trimmed());
params.SetExportLength(sequence_->GetLength());
params.SetExportLength(viewer_node_->GetLength());
if (range_combobox_->currentIndex() == kRangeInToOut
&& sequence_->timeline_points()->workarea()->enabled()) {
params.set_custom_range(sequence_->timeline_points()->workarea()->range());
if (range_combobox_->isEnabled() && range_combobox_->currentIndex() == kRangeInToOut) {
// Assume if this combobox is enabled, that we have timeline points - a check that we make
// in this dialog's constructor
params.set_custom_range(timeline_points_->workarea()->range());
}
if (video_tab_->scaling_method_combobox()->isEnabled()) {
@@ -500,8 +502,8 @@ void ExportDialog::UpdateViewerDimensions()
QMatrix4x4 transform =
ExportParams::GenerateMatrix(static_cast<ExportParams::VideoScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()),
sequence_->video_params().width(),
sequence_->video_params().height(),
viewer_node_->video_params().width(),
viewer_node_->video_params().height(),
static_cast<int>(video_tab_->width_slider()->GetValue()),
static_cast<int>(video_tab_->height_slider()->GetValue()));
+3 -2
View File
@@ -40,7 +40,7 @@ class ExportDialog : public QDialog
{
Q_OBJECT
public:
ExportDialog(Sequence* sequence, QWidget* parent = nullptr);
ExportDialog(ViewerOutput* viewer_node, TimelinePoints* points, QWidget* parent = nullptr);
protected:
virtual void closeEvent(QCloseEvent *e) override;
@@ -51,7 +51,8 @@ private:
ExportParams GenerateParams() const;
Sequence* sequence_;
ViewerOutput* viewer_node_;
TimelinePoints* timeline_points_;
ExportFormat::Format previously_selected_format_;
+1
View File
@@ -24,6 +24,7 @@
#include "node/math/math/math.h"
#include "node/math/merge/merge.h"
#include "node/output/viewer/viewer.h"
#include "project/item/sequence/sequence.h"
namespace olive {
+299 -2
View File
@@ -20,13 +20,39 @@
#include "viewer.h"
#include "config/config.h"
#include "core.h"
#include "node/traverser.h"
#include "widget/videoparamedit/videoparamedit.h"
namespace olive {
#define super Sequence
const QString ViewerOutput::kVideoParamsInput = QStringLiteral("video_param_in");
const QString ViewerOutput::kAudioParamsInput = QStringLiteral("audio_param_in");
const QString ViewerOutput::kTextureInput = QStringLiteral("tex_in");
const QString ViewerOutput::kSamplesInput = QStringLiteral("samples_in");
const uint64_t ViewerOutput::kVideoParamEditMask = VideoParamEdit::kWidthHeight | VideoParamEdit::kInterlacing | VideoParamEdit::kFrameRate | VideoParamEdit::kPixelAspect;
#define super Node
ViewerOutput::ViewerOutput() :
Sequence(true)
video_frame_cache_(this),
audio_playback_cache_(this),
operation_stack_(0)
{
AddInput(kVideoParamsInput, NodeValue::kVideoParams, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable));
SetInputProperty(kVideoParamsInput, QStringLiteral("mask"), QVariant::fromValue(kVideoParamEditMask));
AddInput(kAudioParamsInput, NodeValue::kAudioParams, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable));
AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
AddInput(kSamplesInput, NodeValue::kSamples, InputFlags(kInputFlagNotKeyframable));
}
ViewerOutput::~ViewerOutput()
{
DisconnectAll();
}
Node *ViewerOutput::copy() const
@@ -54,4 +80,275 @@ QString ViewerOutput::Description() const
return tr("Interface between a Viewer panel and the node system.");
}
QString ViewerOutput::duration() const
{
rational timeline_length = GetLength();
int64_t timestamp = Timecode::time_to_timestamp(timeline_length, video_params().time_base());
return Timecode::timestamp_to_timecode(timestamp, video_params().time_base(), Core::instance()->GetTimecodeDisplay());
}
QString ViewerOutput::rate() const
{
return tr("%1 FPS").arg(video_params().time_base().flipped().toDouble());
}
void ViewerOutput::set_default_parameters()
{
int width = Config::Current()["DefaultSequenceWidth"].toInt();
int height = Config::Current()["DefaultSequenceHeight"].toInt();
set_video_params(VideoParams(width,
height,
Config::Current()["DefaultSequenceFrameRate"].value<rational>(),
static_cast<VideoParams::Format>(Config::Current()["OfflinePixelFormat"].toInt()),
VideoParams::kInternalChannelCount,
Config::Current()["DefaultSequencePixelAspect"].value<rational>(),
Config::Current()["DefaultSequenceInterlacing"].value<VideoParams::Interlacing>(),
VideoParams::generate_auto_divider(width, height)));
set_audio_params(AudioParams(Config::Current()["DefaultSequenceAudioFrequency"].toInt(),
Config::Current()["DefaultSequenceAudioLayout"].toULongLong(),
AudioParams::kInternalFormat));
}
void ViewerOutput::ShiftVideoCache(const rational &from, const rational &to)
{
video_frame_cache_.Shift(from, to);
ShiftVideoEvent(from, to);
}
void ViewerOutput::ShiftAudioCache(const rational &from, const rational &to)
{
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, qint64 job_time)
{
Q_UNUSED(element)
if (operation_stack_ == 0) {
if (from == kTextureInput || from == kSamplesInput
|| from == kVideoParamsInput || from == kAudioParamsInput) {
TimeRange invalidated_range(qMax(rational(), range.in()),
qMin(GetLength(), range.out()));
if (invalidated_range.in() != invalidated_range.out()) {
if (from == kTextureInput || from == kVideoParamsInput) {
video_frame_cache_.Invalidate(invalidated_range, job_time);
} else {
audio_playback_cache_.Invalidate(invalidated_range, job_time);
}
}
}
VerifyLength();
}
super::InvalidateCache(range, from, element, job_time);
}
const rational& ViewerOutput::GetLength() const
{
return last_length_;
}
void ViewerOutput::Retranslate()
{
super::Retranslate();
SetInputName(kVideoParamsInput, tr("Video Parameters"));
SetInputName(kAudioParamsInput, tr("Audio Parameters"));
SetInputName(kTextureInput, tr("Texture"));
SetInputName(kSamplesInput, tr("Samples"));
}
void ViewerOutput::VerifyLength()
{
if (operation_stack_ != 0) {
return;
}
NodeTraverser traverser;
rational video_length, audio_length, subtitle_length;
{
video_length = GetCustomLength(Track::kVideo);
if (video_length.isNull() && IsInputConnected(kTextureInput)) {
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kTextureInput), TimeRange(0, 0));
video_length = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
}
video_frame_cache_.SetLength(video_length);
}
{
audio_length = GetCustomLength(Track::kAudio);
if (audio_length.isNull() && IsInputConnected(kSamplesInput)) {
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kSamplesInput), TimeRange(0, 0));
audio_length = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
}
audio_playback_cache_.SetLength(audio_length);
}
{
subtitle_length = GetCustomLength(Track::kSubtitle);
}
rational real_length = qMax(subtitle_length, qMax(video_length, audio_length));
if (real_length != last_length_) {
last_length_ = real_length;
emit LengthChanged(last_length_);
}
}
void ViewerOutput::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
{
if (input == kTextureInput) {
emit TextureInputChanged();
}
super::InputConnectedEvent(input, element, output);
}
void ViewerOutput::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
{
if (input == kTextureInput) {
emit TextureInputChanged();
}
super::InputDisconnectedEvent(input, element, output);
}
rational ViewerOutput::GetCustomLength(Track::Type type) const
{
Q_UNUSED(type)
return rational();
}
void ViewerOutput::BeginOperation()
{
operation_stack_++;
super::BeginOperation();
}
void ViewerOutput::EndOperation()
{
operation_stack_--;
super::EndOperation();
}
void ViewerOutput::InputValueChangedEvent(const QString &input, int element)
{
if (input == kVideoParamsInput) {
VideoParams new_video_params = video_params();
bool size_changed = cached_video_params_.width() != new_video_params.width() || cached_video_params_.height() != new_video_params.height();
bool timebase_changed = cached_video_params_.time_base() != new_video_params.time_base();
bool pixel_aspect_changed = cached_video_params_.pixel_aspect_ratio() != new_video_params.pixel_aspect_ratio();
bool interlacing_changed = cached_video_params_.interlacing() != new_video_params.interlacing();
if (size_changed) {
emit SizeChanged(new_video_params.width(), new_video_params.height());
}
if (pixel_aspect_changed) {
emit PixelAspectChanged(new_video_params.pixel_aspect_ratio());
}
if (interlacing_changed) {
emit InterlacingChanged(new_video_params.interlacing());
}
if (timebase_changed) {
video_frame_cache_.SetTimebase(new_video_params.time_base());
emit TimebaseChanged(new_video_params.time_base());
}
emit VideoParamsChanged();
cached_video_params_ = video_params();
} else if (input == kAudioParamsInput) {
emit AudioParamsChanged();
audio_playback_cache_.SetParameters(audio_params());
}
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<Footage *> footage)
{
foreach (Footage* f, footage) {
QVector<VideoParams> video_streams = f->GetEnabledVideoStreams();
QVector<AudioParams> audio_streams = f->GetEnabledAudioStreams();
foreach (const VideoParams& s, video_streams) {
bool found_video_params = false;
rational using_timebase;
if (s.video_type() == VideoParams::kVideoTypeStill) {
// If this is a still image, we'll use it's resolution but won't set
// `found_video_params` in case something with a frame rate comes along which we'll
// prioritize
using_timebase = video_params().time_base();
} else {
using_timebase = s.frame_rate().flipped();
found_video_params = true;
}
set_video_params(VideoParams(s.width(),
s.height(),
using_timebase,
static_cast<VideoParams::Format>(Config::Current()[QStringLiteral("OfflinePixelFormat")].toInt()),
VideoParams::kInternalChannelCount,
s.pixel_aspect_ratio(),
s.interlacing(),
VideoParams::generate_auto_divider(s.width(), s.height())));
if (found_video_params) {
break;
}
}
if (!audio_streams.isEmpty()) {
const AudioParams& s = audio_streams.first();
set_audio_params(AudioParams(s.sample_rate(), s.channel_layout(), AudioParams::kInternalFormat));
}
}
}
}
+113 -2
View File
@@ -21,7 +21,15 @@
#ifndef VIEWER_H
#define VIEWER_H
#include "project/item/sequence/sequence.h"
#include "common/rational.h"
#include "node/node.h"
#include "node/output/track/track.h"
#include "project/item/footage/footage.h"
#include "render/audioparams.h"
#include "render/audioplaybackcache.h"
#include "render/framehashcache.h"
#include "render/videoparams.h"
#include "render/videoparams.h"
namespace olive {
@@ -30,11 +38,12 @@ namespace olive {
*
* Receives update/time change signals from ViewerPanels and responds by sending them a texture of that frame
*/
class ViewerOutput : public Sequence
class ViewerOutput : public Node
{
Q_OBJECT
public:
ViewerOutput();
virtual ~ViewerOutput() override;
virtual Node* copy() const override;
@@ -43,6 +52,108 @@ public:
virtual QVector<CategoryID> Category() const override;
virtual QString Description() const override;
virtual QString duration() const override;
virtual QString rate() const override;
void set_default_parameters();
void set_parameters_from_footage(const QVector<Footage *> 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, qint64 job_time) override;
VideoParams video_params() const
{
return GetStandardValue(kVideoParamsInput).value<VideoParams>();
}
AudioParams audio_params() const
{
return GetStandardValue(kAudioParamsInput).value<AudioParams>();
}
void set_video_params(const VideoParams &video)
{
SetStandardValue(kVideoParamsInput, QVariant::fromValue(video));
}
void set_audio_params(const AudioParams &audio)
{
SetStandardValue(kAudioParamsInput, QVariant::fromValue(audio));
}
const rational &GetLength() const;
FrameHashCache* video_frame_cache()
{
return &video_frame_cache_;
}
AudioPlaybackCache* audio_playback_cache()
{
return &audio_playback_cache_;
}
virtual void Retranslate() override;
virtual void BeginOperation() override;
virtual void EndOperation() override;
static const QString kVideoParamsInput;
static const QString kAudioParamsInput;
static const QString kTextureInput;
static const QString kSamplesInput;
static const uint64_t kVideoParamEditMask;
signals:
void TimebaseChanged(const rational&);
void LengthChanged(const rational& length);
void SizeChanged(int width, int height);
void PixelAspectChanged(const rational& pixel_aspect);
void InterlacingChanged(VideoParams::Interlacing mode);
void VideoParamsChanged();
void AudioParamsChanged();
void TextureInputChanged();
public slots:
void VerifyLength();
protected:
virtual void InputConnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual rational GetCustomLength(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;
private:
rational last_length_;
FrameHashCache video_frame_cache_;
AudioPlaybackCache audio_playback_cache_;
int operation_stack_;
VideoParams cached_video_params_;
};
}
+1 -16
View File
@@ -108,22 +108,7 @@ void TimeBasedPanel::ShuttleRight()
emit ShuttleRightRequested();
}
TimeBasedWidget *TimeBasedPanel::GetTimeBasedWidget() const
{
return widget_;
}
Sequence *TimeBasedPanel::GetConnectedViewer() const
{
return widget_->GetConnectedNode();
}
TimeRuler *TimeBasedPanel::ruler() const
{
return widget_->ruler();
}
void TimeBasedPanel::ConnectViewerNode(Sequence *node)
void TimeBasedPanel::ConnectViewerNode(ViewerOutput *node)
{
if (widget_->GetConnectedNode() == node) {
return;
+18 -4
View File
@@ -32,15 +32,26 @@ class TimeBasedPanel : public PanelWidget
public:
TimeBasedPanel(const QString& object_name, QWidget *parent = nullptr);
void ConnectViewerNode(Sequence *node);
void ConnectViewerNode(ViewerOutput *node);
void DisconnectViewerNode();
rational GetTime();
Sequence *GetConnectedViewer() const;
ViewerOutput *GetConnectedViewer() const
{
return widget_->GetConnectedNode();
}
TimeRuler* ruler() const;
TimelinePoints* GetConnectedTimelinePoints() const
{
return widget_->GetConnectedTimelinePoints();
}
TimeRuler* ruler() const
{
return widget_->ruler();
}
virtual void ZoomIn() override;
@@ -107,7 +118,10 @@ signals:
void ShuttleRightRequested();
protected:
TimeBasedWidget* GetTimeBasedWidget() const;
TimeBasedWidget* GetTimeBasedWidget() const
{
return widget_;
}
void SetTimeBasedWidget(TimeBasedWidget* widget);
+25 -302
View File
@@ -22,68 +22,35 @@
#include <QThread>
#include "config/config.h"
#include "common/channellayout.h"
#include "common/timecodefunctions.h"
#include "common/xmlutils.h"
#include "node/factory.h"
#include "panel/panelmanager.h"
#include "panel/node/node.h"
#include "panel/curve/curve.h"
#include "panel/param/param.h"
#include "panel/timeline/timeline.h"
#include "panel/sequenceviewer/sequenceviewer.h"
#include "ui/icons/icons.h"
#include "widget/videoparamedit/videoparamedit.h"
namespace olive {
const QString Sequence::kVideoParamsInput = QStringLiteral("video_param_in");
const QString Sequence::kAudioParamsInput = QStringLiteral("audio_param_in");
const QString Sequence::kTextureInput = QStringLiteral("tex_in");
const QString Sequence::kSamplesInput = QStringLiteral("samples_in");
const QString Sequence::kTrackInputFormat = QStringLiteral("track_in_%1");
const uint64_t Sequence::kVideoParamEditMask = VideoParamEdit::kWidthHeight | VideoParamEdit::kInterlacing | VideoParamEdit::kFrameRate | VideoParamEdit::kPixelAspect;
#define super ViewerOutput
#define super Node
Sequence::Sequence(bool viewer_only_mode) :
video_frame_cache_(this),
audio_playback_cache_(this),
operation_stack_(0)
Sequence::Sequence()
{
AddInput(kVideoParamsInput, NodeValue::kVideoParams, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable));
SetInputProperty(kVideoParamsInput, QStringLiteral("mask"), QVariant::fromValue(kVideoParamEditMask));
// Create TrackList instances
track_lists_.resize(Track::kCount);
AddInput(kAudioParamsInput, NodeValue::kAudioParams, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable));
for (int i=0;i<Track::kCount;i++) {
// Create track input
QString track_input_id = kTrackInputFormat.arg(i);
AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
AddInput(kSamplesInput, NodeValue::kSamples, InputFlags(kInputFlagNotKeyframable));
AddInput(track_input_id, NodeValue::kNone, InputFlags(kInputFlagNotKeyframable | kInputFlagArray));
if (!viewer_only_mode) {
// Create TrackList instances
track_lists_.resize(Track::kCount);
IgnoreInvalidationsFrom(track_input_id);
for (int i=0;i<Track::kCount;i++) {
// Create track input
QString track_input_id = kTrackInputFormat.arg(i);
AddInput(track_input_id, NodeValue::kNone, InputFlags(kInputFlagNotKeyframable | kInputFlagArray));
IgnoreInvalidationsFrom(track_input_id);
TrackList* list = new TrackList(this, static_cast<Track::Type>(i), track_input_id);
track_lists_.replace(i, list);
connect(list, &TrackList::TrackListChanged, this, &Sequence::UpdateTrackCache);
connect(list, &TrackList::LengthChanged, this, &Sequence::VerifyLength);
connect(list, &TrackList::TrackAdded, this, &Sequence::TrackAdded);
connect(list, &TrackList::TrackRemoved, this, &Sequence::TrackRemoved);
}
TrackList* list = new TrackList(this, static_cast<Track::Type>(i), track_input_id);
track_lists_.replace(i, list);
connect(list, &TrackList::TrackListChanged, this, &Sequence::UpdateTrackCache);
connect(list, &TrackList::LengthChanged, this, &Sequence::VerifyLength);
connect(list, &TrackList::TrackAdded, this, &Sequence::TrackAdded);
connect(list, &TrackList::TrackRemoved, this, &Sequence::TrackRemoved);
}
// Create UUID for this node
uuid_ = QUuid::createUuid();
}
Sequence::~Sequence()
@@ -103,80 +70,6 @@ QIcon Sequence::icon() const
return icon::Sequence;
}
QString Sequence::duration() const
{
rational timeline_length = GetLength();
int64_t timestamp = Timecode::time_to_timestamp(timeline_length, video_params().time_base());
return Timecode::timestamp_to_timecode(timestamp, video_params().time_base(), Core::instance()->GetTimecodeDisplay());
}
QString Sequence::rate() const
{
return tr("%1 FPS").arg(video_params().time_base().flipped().toDouble());
}
void Sequence::set_default_parameters()
{
int width = Config::Current()["DefaultSequenceWidth"].toInt();
int height = Config::Current()["DefaultSequenceHeight"].toInt();
set_video_params(VideoParams(width,
height,
Config::Current()["DefaultSequenceFrameRate"].value<rational>(),
static_cast<VideoParams::Format>(Config::Current()["OfflinePixelFormat"].toInt()),
VideoParams::kInternalChannelCount,
Config::Current()["DefaultSequencePixelAspect"].value<rational>(),
Config::Current()["DefaultSequenceInterlacing"].value<VideoParams::Interlacing>(),
VideoParams::generate_auto_divider(width, height)));
set_audio_params(AudioParams(Config::Current()["DefaultSequenceAudioFrequency"].toInt(),
Config::Current()["DefaultSequenceAudioLayout"].toULongLong(),
AudioParams::kInternalFormat));
}
void Sequence::set_parameters_from_footage(const QVector<Footage *> footage)
{
foreach (Footage* f, footage) {
QVector<VideoParams> video_streams = f->GetEnabledVideoStreams();
QVector<AudioParams> audio_streams = f->GetEnabledAudioStreams();
foreach (const VideoParams& s, video_streams) {
bool found_video_params = false;
rational using_timebase;
if (s.video_type() == VideoParams::kVideoTypeStill) {
// If this is a still image, we'll use it's resolution but won't set
// `found_video_params` in case something with a frame rate comes along which we'll
// prioritize
using_timebase = video_params().time_base();
} else {
using_timebase = s.frame_rate().flipped();
found_video_params = true;
}
set_video_params(VideoParams(s.width(),
s.height(),
using_timebase,
static_cast<VideoParams::Format>(Config::Current()[QStringLiteral("OfflinePixelFormat")].toInt()),
VideoParams::kInternalChannelCount,
s.pixel_aspect_ratio(),
s.interlacing(),
VideoParams::generate_auto_divider(s.width(), s.height())));
if (found_video_params) {
break;
}
}
if (!audio_streams.isEmpty()) {
const AudioParams& s = audio_streams.first();
set_audio_params(AudioParams(s.sample_rate(), s.channel_layout(), AudioParams::kInternalFormat));
}
}
}
QVector<Track *> Sequence::GetUnlockedTracks() const
{
QVector<Track*> tracks = GetTracks();
@@ -195,12 +88,6 @@ void Sequence::Retranslate()
{
super::Retranslate();
SetInputName(kVideoParamsInput, tr("Video Parameters"));
SetInputName(kAudioParamsInput, tr("Audio Parameters"));
SetInputName(kTextureInput, tr("Texture"));
SetInputName(kSamplesInput, tr("Samples"));
for (int i=0;i<Track::kCount;i++) {
QString input_name;
@@ -246,15 +133,11 @@ rational Sequence::GetCustomLength(Track::Type type) const
void Sequence::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
{
if (input == kTextureInput) {
emit TextureInputChanged();
} else {
foreach (TrackList* list, track_lists_) {
if (list->track_input() == input) {
// Return because we found our input
list->TrackConnected(output.node(), element);
return;
}
foreach (TrackList* list, track_lists_) {
if (list->track_input() == input) {
// Return because we found our input
list->TrackConnected(output.node(), element);
return;
}
}
@@ -263,15 +146,11 @@ void Sequence::InputConnectedEvent(const QString &input, int element, const Node
void Sequence::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
{
if (input == kTextureInput) {
emit TextureInputChanged();
} else {
foreach (TrackList* list, track_lists_) {
if (list->track_input() == input) {
// Return because we found our input
list->TrackDisconnected(output.node(), element);
return;
}
foreach (TrackList* list, track_lists_) {
if (list->track_input() == input) {
// Return because we found our input
list->TrackDisconnected(output.node(), element);
return;
}
}
@@ -296,113 +175,6 @@ void Sequence::UpdateTrackCache()
}
}
void Sequence::ShiftVideoCache(const rational &from, const rational &to)
{
video_frame_cache_.Shift(from, to);
ShiftVideoEvent(from, to);
}
void Sequence::ShiftAudioCache(const rational &from, const rational &to)
{
audio_playback_cache_.Shift(from, to);
ShiftAudioEvent(from, to);
}
void Sequence::ShiftCache(const rational &from, const rational &to)
{
ShiftVideoCache(from, to);
ShiftAudioCache(from, to);
}
void Sequence::InvalidateCache(const TimeRange& range, const QString& from, int element, qint64 job_time)
{
Q_UNUSED(element)
if (operation_stack_ == 0) {
if (from == kTextureInput || from == kSamplesInput) {
TimeRange invalidated_range(qMax(rational(), range.in()),
qMin(GetLength(), range.out()));
if (invalidated_range.in() != invalidated_range.out()) {
if (from == kTextureInput) {
video_frame_cache_.Invalidate(invalidated_range, job_time);
} else {
audio_playback_cache_.Invalidate(invalidated_range, job_time);
}
}
}
VerifyLength();
}
super::InvalidateCache(range, from, element, job_time);
}
const rational& Sequence::GetLength() const
{
return last_length_;
}
void Sequence::VerifyLength()
{
if (operation_stack_ != 0) {
return;
}
NodeTraverser traverser;
rational video_length, audio_length, subtitle_length;
{
video_length = GetCustomLength(Track::kVideo);
if (video_length.isNull() && IsInputConnected(kTextureInput)) {
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kTextureInput), TimeRange(0, 0));
video_length = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
}
video_frame_cache_.SetLength(video_length);
}
{
audio_length = GetCustomLength(Track::kAudio);
if (audio_length.isNull() && IsInputConnected(kSamplesInput)) {
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kSamplesInput), TimeRange(0, 0));
audio_length = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
}
audio_playback_cache_.SetLength(audio_length);
}
{
subtitle_length = GetCustomLength(Track::kSubtitle);
}
rational real_length = qMax(subtitle_length, qMax(video_length, audio_length));
if (real_length != last_length_) {
last_length_ = real_length;
emit LengthChanged(last_length_);
}
}
void Sequence::BeginOperation()
{
operation_stack_++;
super::BeginOperation();
}
void Sequence::EndOperation()
{
operation_stack_--;
super::EndOperation();
}
void Sequence::LoadInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt *cancelled)
{
Q_UNUSED(xml_node_data)
@@ -426,53 +198,4 @@ void Sequence::SaveInternal(QXmlStreamWriter *writer) const
writer->writeEndElement(); // points
}
void Sequence::InputValueChangedEvent(const QString &input, int element)
{
if (input == kVideoParamsInput) {
VideoParams new_video_params = video_params();
bool size_changed = cached_video_params_.width() != new_video_params.width() || cached_video_params_.height() != new_video_params.height();
bool timebase_changed = cached_video_params_.time_base() != new_video_params.time_base();
bool pixel_aspect_changed = cached_video_params_.pixel_aspect_ratio() != new_video_params.pixel_aspect_ratio();
bool interlacing_changed = cached_video_params_.interlacing() != new_video_params.interlacing();
if (size_changed) {
emit SizeChanged(new_video_params.width(), new_video_params.height());
}
if (pixel_aspect_changed) {
emit PixelAspectChanged(new_video_params.pixel_aspect_ratio());
}
if (interlacing_changed) {
emit InterlacingChanged(new_video_params.interlacing());
}
if (timebase_changed) {
video_frame_cache_.SetTimebase(new_video_params.time_base());
emit TimebaseChanged(new_video_params.time_base());
}
emit VideoParamsChanged();
cached_video_params_ = video_params();
video_frame_cache_.InvalidateAll();
} else if (input == kAudioParamsInput) {
emit AudioParamsChanged();
// This will automatically InvalidateAll
audio_playback_cache_.SetParameters(audio_params());
}
}
void Sequence::ShiftVideoEvent(const rational &from, const rational &to)
{
Q_UNUSED(from)
Q_UNUSED(to)
}
}
+14 -124
View File
@@ -21,23 +21,8 @@
#ifndef SEQUENCE_H
#define SEQUENCE_H
#include <QUuid>
#include "common/rational.h"
#include "node/block/block.h"
#include "node/graph.h"
#include "node/node.h"
#include "node/output/track/track.h"
#include "node/output/track/tracklist.h"
#include "node/traverser.h"
#include "project/item/footage/footage.h"
#include "render/audioparams.h"
#include "render/audioplaybackcache.h"
#include "render/framehashcache.h"
#include "render/videoparams.h"
#include "render/videoparams.h"
#include "timeline/timelinecommon.h"
#include "timeline/timelinepoints.h"
#include "node/output/viewer/viewer.h"
#include "timeline/timelinepoints.h"
namespace olive {
@@ -45,11 +30,11 @@ namespace olive {
/**
* @brief The main timeline object, an graph of edited clips that forms a complete edit
*/
class Sequence : public Node, public TimelinePoints
class Sequence : public ViewerOutput
{
Q_OBJECT
public:
Sequence(bool viewer_only_mode = false);
Sequence();
virtual ~Sequence() override;
@@ -82,13 +67,6 @@ public:
virtual QIcon icon() const override;
virtual QString duration() const override;
virtual QString rate() const override;
void set_default_parameters();
void set_parameters_from_footage(const QVector<Footage *> footage);
const QVector<Track *> &GetTracks() const
{
return track_cache_;
@@ -109,130 +87,42 @@ public:
return track_lists_.at(type);
}
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, qint64 job_time) override;
VideoParams video_params() const
{
return GetStandardValue(kVideoParamsInput).value<VideoParams>();
}
AudioParams audio_params() const
{
return GetStandardValue(kAudioParamsInput).value<AudioParams>();
}
void set_video_params(const VideoParams &video)
{
SetStandardValue(kVideoParamsInput, QVariant::fromValue(video));
}
void set_audio_params(const AudioParams &audio)
{
SetStandardValue(kAudioParamsInput, QVariant::fromValue(audio));
}
const rational &GetLength() const;
virtual void Retranslate() override;
FrameHashCache* video_frame_cache()
{
return &video_frame_cache_;
}
AudioPlaybackCache* audio_playback_cache()
{
return &audio_playback_cache_;
}
virtual void BeginOperation() override;
virtual void EndOperation() override;
static const QString kVideoParamsInput;
static const QString kAudioParamsInput;
static const QString kTextureInput;
static const QString kSamplesInput;
static const QString kTrackInputFormat;
static const uint64_t kVideoParamEditMask;
TimelinePoints* timeline_points()
{
return &timeline_points_;
}
const QUuid& uuid() const
{
return uuid_;
}
virtual bool IsItem() const override
{
return true;
}
signals:
void TimebaseChanged(const rational&);
void LengthChanged(const rational& length);
void SizeChanged(int width, int height);
void PixelAspectChanged(const rational& pixel_aspect);
void InterlacingChanged(VideoParams::Interlacing mode);
void VideoParamsChanged();
void AudioParamsChanged();
void TrackAdded(Track* track);
void TrackRemoved(Track* track);
void TextureInputChanged();
public slots:
void VerifyLength();
protected:
virtual void InputConnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual rational GetCustomLength(Track::Type type) const;
virtual void ShiftVideoEvent(const rational &from, const rational &to);
virtual void ShiftAudioEvent(const rational &from, const rational &to);
virtual void LoadInternal(QXmlStreamReader* reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt* cancelled) override;
virtual void SaveInternal(QXmlStreamWriter *writer) const override;
virtual void InputValueChangedEvent(const QString& input, int element) override;
virtual void ShiftAudioEvent(const rational &from, const rational &to) override;
virtual void InputConnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual rational GetCustomLength(Track::Type type) const override;
signals:
void TrackAdded(Track* track);
void TrackRemoved(Track* track);
private:
QVector<TrackList*> track_lists_;
QVector<Track*> track_cache_;
QUuid uuid_;
rational last_length_;
FrameHashCache video_frame_cache_;
AudioPlaybackCache audio_playback_cache_;
int operation_stack_;
VideoParams cached_video_params_;
TimelinePoints timeline_points_;
private slots:
+2 -1
View File
@@ -21,8 +21,9 @@
#ifndef PROJECT_H
#define PROJECT_H
#include <QObject>
#include <memory>
#include <QObject>
#include <QUuid>
#include "node/project/projectsettings/projectsettings.h"
#include "node/output/viewer/viewer.h"
+4 -5
View File
@@ -3,7 +3,6 @@
#include <QApplication>
#include <QtConcurrent/QtConcurrent>
#include "project/item/sequence/sequence.h"
#include "project/project.h"
#include "render/rendermanager.h"
#include "render/renderprocessor.h"
@@ -65,13 +64,13 @@ void PreviewAutoCacher::SetPaused(bool paused)
}
}
void PreviewAutoCacher::GenerateHashes(Sequence *viewer, FrameHashCache* cache, const QVector<rational> &times, qint64 job_time)
void PreviewAutoCacher::GenerateHashes(ViewerOutput *viewer, FrameHashCache* cache, const QVector<rational> &times, qint64 job_time)
{
std::vector<QByteArray> existing_hashes;
foreach (const rational& time, times) {
// See if hash already exists in disk cache
QByteArray hash = RenderManager::Hash(viewer->GetConnectedNode(Sequence::kTextureInput), viewer->video_params(), time);
QByteArray hash = RenderManager::Hash(viewer->GetConnectedNode(ViewerOutput::kTextureInput), viewer->video_params(), time);
// Check memory list since disk checking is slow
bool hash_exists = (std::find(existing_hashes.begin(), existing_hashes.end(), hash) != existing_hashes.end());
@@ -590,7 +589,7 @@ void PreviewAutoCacher::ForceCacheRange(const TimeRange &range)
RequeueFrames();
}
void PreviewAutoCacher::SetViewerNode(Sequence *viewer_node)
void PreviewAutoCacher::SetViewerNode(ViewerOutput *viewer_node)
{
if (viewer_node_ == viewer_node) {
return;
@@ -662,7 +661,7 @@ void PreviewAutoCacher::SetViewerNode(Sequence *viewer_node)
}
// Find copied viewer node
copied_viewer_node_ = static_cast<Sequence*>(copy_map_.value(viewer_node_));
copied_viewer_node_ = static_cast<ViewerOutput*>(copy_map_.value(viewer_node_));
// Copy parameters
copied_viewer_node_->set_video_params(viewer_node_->video_params());
+4 -4
View File
@@ -31,7 +31,7 @@ public:
/**
* @brief Set the viewer node to auto-cache
*/
void SetViewerNode(Sequence *viewer_node);
void SetViewerNode(ViewerOutput *viewer_node);
/**
* @brief If the mouse is held during the next cache invalidation, cache anyway
@@ -85,7 +85,7 @@ public:
}
private:
static void GenerateHashes(Sequence *viewer, FrameHashCache *cache, const QVector<rational>& times, qint64 job_time);
static void GenerateHashes(ViewerOutput *viewer, FrameHashCache *cache, const QVector<rational>& times, qint64 job_time);
void TryRender();
@@ -125,13 +125,13 @@ private:
NodeOutput output;
};
Sequence* viewer_node_;
ViewerOutput* viewer_node_;
Project copied_project_;
QVector<QueuedJob> graph_update_queue_;
QHash<Node*, Node*> copy_map_;
Sequence* copied_viewer_node_;
ViewerOutput* copied_viewer_node_;
QVector<Node*> created_nodes_;
bool paused_;
+4 -4
View File
@@ -99,7 +99,7 @@ QByteArray RenderManager::Hash(const Node *n, const VideoParams &params, const r
return hasher.result();
}
RenderTicketPtr RenderManager::RenderFrame(Sequence* viewer, ColorManager* color_manager,
RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* color_manager,
const rational& time, RenderMode::Mode mode,
FrameHashCache* cache, bool prioritize)
{
@@ -117,7 +117,7 @@ RenderTicketPtr RenderManager::RenderFrame(Sequence* viewer, ColorManager* color
prioritize);
}
RenderTicketPtr RenderManager::RenderFrame(Sequence* viewer, ColorManager* color_manager,
RenderTicketPtr RenderManager::RenderFrame(ViewerOutput *viewer, ColorManager* color_manager,
const rational& time, RenderMode::Mode mode,
const VideoParams &video_params, const AudioParams &audio_params,
const QSize& force_size,
@@ -156,12 +156,12 @@ RenderTicketPtr RenderManager::RenderFrame(Sequence* viewer, ColorManager* color
return ticket;
}
RenderTicketPtr RenderManager::RenderAudio(Sequence* viewer, const TimeRange& r, bool generate_waveforms, bool prioritize)
RenderTicketPtr RenderManager::RenderAudio(ViewerOutput* viewer, const TimeRange& r, bool generate_waveforms, bool prioritize)
{
return RenderAudio(viewer, r, viewer->audio_params(), generate_waveforms, prioritize);
}
RenderTicketPtr RenderManager::RenderAudio(Sequence* viewer, const TimeRange &r, const AudioParams &params, bool generate_waveforms, bool prioritize)
RenderTicketPtr RenderManager::RenderAudio(ViewerOutput* viewer, const TimeRange &r, const AudioParams &params, bool generate_waveforms, bool prioritize)
{
// Create ticket
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
+4 -4
View File
@@ -80,10 +80,10 @@ public:
*
* This function is thread-safe.
*/
RenderTicketPtr RenderFrame(Sequence *viewer, ColorManager* color_manager,
RenderTicketPtr RenderFrame(ViewerOutput *viewer, ColorManager* color_manager,
const rational& time, RenderMode::Mode mode,
FrameHashCache* cache = nullptr, bool prioritize = false);
RenderTicketPtr RenderFrame(Sequence* viewer, ColorManager* color_manager,
RenderTicketPtr RenderFrame(ViewerOutput* viewer, ColorManager* color_manager,
const rational& time, RenderMode::Mode mode,
const VideoParams& video_params, const AudioParams& audio_params,
const QSize& force_size,
@@ -101,8 +101,8 @@ public:
*
* This function is thread-safe.
*/
RenderTicketPtr RenderAudio(Sequence* viewer, const TimeRange& r, const AudioParams& params, bool generate_waveforms, bool prioritize = false);
RenderTicketPtr RenderAudio(Sequence *viewer, const TimeRange& r, bool generate_waveforms, bool prioritize = false);
RenderTicketPtr RenderAudio(ViewerOutput* viewer, const TimeRange& r, const AudioParams& params, bool generate_waveforms, bool prioritize = false);
RenderTicketPtr RenderAudio(ViewerOutput *viewer, const TimeRange& r, bool generate_waveforms, bool prioritize = false);
RenderTicketPtr SaveFrameToCache(FrameHashCache* cache, FramePtr frame, const QByteArray& hash, bool prioritize = false);
+4 -4
View File
@@ -54,11 +54,11 @@ void RenderProcessor::Run()
switch (type) {
case RenderManager::kTypeVideo:
{
Sequence* viewer = Node::ValueToPtr<Sequence>(ticket_->property("viewer"));
ViewerOutput* viewer = Node::ValueToPtr<ViewerOutput>(ticket_->property("viewer"));
const VideoParams& video_params = ticket_->property("vparam").value<VideoParams>();
rational time = ticket_->property("time").value<rational>();
NodeValueTable table = ProcessInput(viewer, Sequence::kTextureInput,
NodeValueTable table = ProcessInput(viewer, ViewerOutput::kTextureInput,
TimeRange(time, time + video_params.time_base()));
TexturePtr texture = table.Get(NodeValue::kTexture).value<TexturePtr>();
@@ -130,10 +130,10 @@ void RenderProcessor::Run()
}
case RenderManager::kTypeAudio:
{
Sequence* viewer = Node::ValueToPtr<Sequence>(ticket_->property("viewer"));
ViewerOutput* viewer = Node::ValueToPtr<ViewerOutput>(ticket_->property("viewer"));
TimeRange time = ticket_->property("time").value<TimeRange>();
NodeValueTable table = ProcessInput(viewer, Sequence::kSamplesInput, time);
NodeValueTable table = ProcessInput(viewer, ViewerOutput::kSamplesInput, time);
ticket_->Finish(table.Get(NodeValue::kSamples), IsCancelled());
break;
+1 -1
View File
@@ -25,7 +25,7 @@
namespace olive {
ExportTask::ExportTask(Sequence *viewer_node,
ExportTask::ExportTask(ViewerOutput *viewer_node,
ColorManager* color_manager,
const ExportParams& params) :
RenderTask(viewer_node, params.video_params(), params.audio_params()),
+1 -1
View File
@@ -33,7 +33,7 @@ class ExportTask : public RenderTask
{
Q_OBJECT
public:
ExportTask(Sequence *viewer_node, ColorManager *color_manager, const ExportParams &params);
ExportTask(ViewerOutput *viewer_node, ColorManager *color_manager, const ExportParams &params);
protected:
virtual bool Run() override;
+1 -1
View File
@@ -25,7 +25,7 @@
namespace olive {
RenderTask::RenderTask(Sequence* viewer, const VideoParams &vparams, const AudioParams &aparams) :
RenderTask::RenderTask(ViewerOutput *viewer, const VideoParams &vparams, const AudioParams &aparams) :
viewer_(viewer),
video_params_(vparams),
audio_params_(aparams),
+3 -3
View File
@@ -35,7 +35,7 @@ class RenderTask : public Task
{
Q_OBJECT
public:
RenderTask(Sequence* viewer, const VideoParams &vparams, const AudioParams &aparams);
RenderTask(ViewerOutput* viewer, const VideoParams &vparams, const AudioParams &aparams);
virtual ~RenderTask() override;
@@ -53,7 +53,7 @@ protected:
virtual void AudioDownloaded(const TimeRange& range, SampleBufferPtr samples, qint64 job_time) = 0;
Sequence* viewer() const
ViewerOutput* viewer() const
{
return viewer_;
}
@@ -87,7 +87,7 @@ private:
void StartTicket(const QByteArray &hash, QThread *watcher_thread, ColorManager *manager, const rational &time, RenderMode::Mode mode, FrameHashCache *cache, const QSize &force_size, const QMatrix4x4 &force_matrix, VideoParams::Format force_format, ColorProcessorPtr force_color_output);
Sequence* viewer_;
ViewerOutput* viewer_;
VideoParams video_params_;
+1 -1
View File
@@ -185,7 +185,7 @@ void CurveWidget::TimeTargetChangedEvent(Node *target)
view_->SetTimeTarget(target);
}
void CurveWidget::ConnectedNodeChanged(Sequence *n)
void CurveWidget::ConnectedNodeChanged(ViewerOutput *n)
{
SetTimeTarget(n);
}
+1 -1
View File
@@ -67,7 +67,7 @@ protected:
virtual void TimeTargetChangedEvent(Node* target) override;
virtual void ConnectedNodeChanged(Sequence* n) override;
virtual void ConnectedNodeChanged(ViewerOutput* n) override;
private:
void SetKeyframeButtonEnabled(bool enable);
+1 -1
View File
@@ -226,7 +226,7 @@ void NodeParamView::TimeChangedEvent(const int64_t &timestamp)
UpdateItemTime(timestamp);
}
void NodeParamView::ConnectedNodeChanged(Sequence *n)
void NodeParamView::ConnectedNodeChanged(ViewerOutput *n)
{
// Set viewer as a time target
keyframe_view_->SetTimeTarget(n);
+1 -1
View File
@@ -96,7 +96,7 @@ protected:
virtual void TimebaseChangedEvent(const rational&) override;
virtual void TimeChangedEvent(const int64_t &) override;
virtual void ConnectedNodeChanged(Sequence* n) override;
virtual void ConnectedNodeChanged(ViewerOutput* n) override;
private:
void UpdateItemTime(const int64_t &timestamp);
+11 -5
View File
@@ -68,12 +68,12 @@ const int64_t &TimeBasedWidget::GetTimestamp() const
return ruler_->GetTime();
}
Sequence *TimeBasedWidget::GetConnectedNode() const
ViewerOutput *TimeBasedWidget::GetConnectedNode() const
{
return viewer_node_;
}
void TimeBasedWidget::ConnectViewerNode(Sequence *node)
void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
{
if (viewer_node_ == node) {
return;
@@ -101,7 +101,7 @@ void TimeBasedWidget::ConnectViewerNode(Sequence *node)
if (viewer_node_) {
connect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll);
if ((points_ = ConnectTimelinePoints())) {
if ((points_ = GetTimelinePointsToConnect())) {
ruler()->ConnectTimelinePoints(points_);
scrollbar_->ConnectTimelinePoints(points_);
}
@@ -242,9 +242,15 @@ void TimeBasedWidget::resizeEvent(QResizeEvent *event)
UpdateMaximumScroll();
}
TimelinePoints *TimeBasedWidget::ConnectTimelinePoints()
TimelinePoints *TimeBasedWidget::GetTimelinePointsToConnect()
{
return viewer_node_->timeline_points();
Sequence* sequence = dynamic_cast<Sequence*>(viewer_node_);
if (sequence) {
return sequence->timeline_points();
}
return nullptr;
}
Project *TimeBasedWidget::GetTimelinePointsProject()
+9 -9
View File
@@ -46,9 +46,11 @@ public:
void ZoomOut();
Sequence* GetConnectedNode() const;
ViewerOutput* GetConnectedNode() const;
void ConnectViewerNode(Sequence *node);
TimelinePoints* GetConnectedTimelinePoints() const;
void ConnectViewerNode(ViewerOutput *node);
void SetScaleAndCenterOnPlayhead(const double& scale);
@@ -105,22 +107,20 @@ protected:
virtual void ScaleChangedEvent(const double &) override;
virtual void ConnectedNodeChanged(Sequence*){}
virtual void ConnectedNodeChanged(ViewerOutput*){}
virtual void ConnectNodeInternal(Sequence*){}
virtual void ConnectNodeInternal(ViewerOutput*){}
virtual void DisconnectNodeInternal(Sequence*){}
virtual void DisconnectNodeInternal(ViewerOutput*){}
void SetAutoMaxScrollBar(bool e);
virtual void resizeEvent(QResizeEvent *event) override;
virtual TimelinePoints* ConnectTimelinePoints();
virtual TimelinePoints* GetTimelinePointsToConnect();
virtual Project* GetTimelinePointsProject();
TimelinePoints* GetConnectedTimelinePoints() const;
void ConnectTimelineView(TimeBasedView* base, bool connect_time_change_event = true);
void PassWheelEventsToScrollBar(QObject* object);
@@ -189,7 +189,7 @@ private:
bool UserIsDraggingPlayhead() const;
Sequence* viewer_node_;
ViewerOutput* viewer_node_;
TimeRuler* ruler_;
+2 -2
View File
@@ -1395,9 +1395,9 @@ public:
QString relevant_input;
if (timeline_->type() == Track::kVideo) {
relevant_input = Sequence::kTextureInput;
relevant_input = ViewerOutput::kTextureInput;
} else {
relevant_input = Sequence::kSamplesInput;
relevant_input = ViewerOutput::kSamplesInput;
}
if (!timeline_->parent()->IsInputConnected(relevant_input)) {
+10 -8
View File
@@ -218,10 +218,12 @@ void TimelineWidget::ScaleChangedEvent(const double &scale)
}
}
void TimelineWidget::ConnectNodeInternal(Sequence *n)
void TimelineWidget::ConnectNodeInternal(ViewerOutput *n)
{
connect(n, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack);
connect(n, &ViewerOutput::TrackRemoved, this, &TimelineWidget::RemoveTrack);
Sequence* s = static_cast<Sequence*>(n);
connect(s, &Sequence::TrackAdded, this, &TimelineWidget::AddTrack);
connect(s, &Sequence::TrackRemoved, this, &TimelineWidget::RemoveTrack);
connect(n, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase);
ruler()->SetPlaybackCache(n->video_frame_cache());
@@ -229,7 +231,6 @@ void TimelineWidget::ConnectNodeInternal(Sequence *n)
SetTimebase(n->video_params().time_base());
for (int i=0;i<views_.size();i++) {
Sequence* s = static_cast<Sequence*>(n);
Track::Type track_type = static_cast<Track::Type>(i);
TimelineView* view = views_.at(i)->view();
TrackList* track_list = s->track_list(track_type);
@@ -246,15 +247,16 @@ void TimelineWidget::ConnectNodeInternal(Sequence *n)
}
}
void TimelineWidget::DisconnectNodeInternal(Sequence *n)
void TimelineWidget::DisconnectNodeInternal(ViewerOutput *n)
{
disconnect(n, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack);
disconnect(n, &ViewerOutput::TrackRemoved, this, &TimelineWidget::RemoveTrack);
Sequence* s = static_cast<Sequence*>(n);
disconnect(s, &Sequence::TrackAdded, this, &TimelineWidget::AddTrack);
disconnect(s, &Sequence::TrackRemoved, this, &TimelineWidget::RemoveTrack);
disconnect(n, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase);
DeselectAll();
Sequence* s = static_cast<Sequence*>(n);
foreach (Track* track, s->GetTracks()) {
RemoveTrack(track);
}
+2 -2
View File
@@ -245,8 +245,8 @@ protected:
virtual void TimeChangedEvent(const int64_t &) override;
virtual void ScaleChangedEvent(const double &) override;
virtual void ConnectNodeInternal(Sequence* n) override;
virtual void DisconnectNodeInternal(Sequence* n) override;
virtual void ConnectNodeInternal(ViewerOutput* n) override;
virtual void DisconnectNodeInternal(ViewerOutput* n) override;
virtual void CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void* userdata) override;
virtual void PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, void* userdata) override;
+1 -1
View File
@@ -102,7 +102,7 @@ void AddTool::MouseRelease(TimelineViewMouseEvent *event)
command->add_child(new NodeAddCommand(graph,
clip));
command->add_child(new TrackPlaceBlockCommand(static_cast<Sequence*>(parent()->GetConnectedNode())->track_list(track.type()),
command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(track.type()),
track.index(),
clip,
ghost_->GetAdjustedIn()));
+3 -4
View File
@@ -313,12 +313,11 @@ void ImportTool::DropGhosts(bool insert)
MultiUndoCommand* command = new MultiUndoCommand();
NodeGraph* dst_graph = nullptr;
Sequence* sequence = nullptr;
Sequence* sequence = this->sequence();
bool open_sequence = false;
if (parent()->GetConnectedNode()) {
sequence = parent()->GetConnectedNode();
dst_graph = parent()->GetConnectedNode()->parent();
if (sequence) {
dst_graph = sequence->parent();
} else {
// There's no active timeline here, ask the user what to do
+1 -1
View File
@@ -91,7 +91,7 @@ void FootageViewerWidget::SetFootage(Footage *footage)
}
}
TimelinePoints *FootageViewerWidget::ConnectTimelinePoints()
TimelinePoints *FootageViewerWidget::GetTimelinePointsToConnect()
{
return footage_;
}
+1 -1
View File
@@ -36,7 +36,7 @@ public:
void SetFootage(Footage* footage);
protected:
virtual TimelinePoints* ConnectTimelinePoints() override;
virtual TimelinePoints* GetTimelinePointsToConnect() override;
virtual Project* GetTimelinePointsProject() override;
+11 -10
View File
@@ -35,7 +35,6 @@
#include "common/ratiodialog.h"
#include "common/timecodefunctions.h"
#include "config/config.h"
#include "project/item/sequence/sequence.h"
#include "project/project.h"
#include "render/rendermanager.h"
#include "task/taskmanager.h"
@@ -44,12 +43,14 @@
namespace olive {
#define super TimeBasedWidget
QVector<ViewerWidget*> ViewerWidget::instances_;
const int kMaxPreQueueSize = 16;
ViewerWidget::ViewerWidget(QWidget *parent) :
TimeBasedWidget(false, true, parent),
super(false, true, parent),
playback_speed_(0),
frame_cache_job_time_(0),
color_menu_enabled_(true),
@@ -168,7 +169,7 @@ void ViewerWidget::TimeChangedEvent(const int64_t &i)
last_time_ = i;
}
void ViewerWidget::ConnectNodeInternal(Sequence *n)
void ViewerWidget::ConnectNodeInternal(ViewerOutput *n)
{
connect(n, &ViewerOutput::SizeChanged, this, &ViewerWidget::SetViewerResolution);
connect(n, &ViewerOutput::PixelAspectChanged, this, &ViewerWidget::SetViewerPixelAspect);
@@ -220,7 +221,7 @@ void ViewerWidget::ConnectNodeInternal(Sequence *n)
ForceUpdate();
}
void ViewerWidget::DisconnectNodeInternal(Sequence *n)
void ViewerWidget::DisconnectNodeInternal(ViewerOutput *n)
{
PauseInternal();
@@ -252,21 +253,21 @@ void ViewerWidget::DisconnectNodeInternal(Sequence *n)
QMetaObject::invokeMethod(this, "UpdateStack", Qt::QueuedConnection);
}
void ViewerWidget::ConnectedNodeChanged(Sequence *n)
void ViewerWidget::ConnectedNodeChanged(ViewerOutput *n)
{
auto_cacher_.SetViewerNode(n);
}
void ViewerWidget::ScaleChangedEvent(const double &s)
{
TimeBasedWidget::ScaleChangedEvent(s);
super::ScaleChangedEvent(s);
waveform_view_->SetScale(s);
}
void ViewerWidget::resizeEvent(QResizeEvent *event)
{
TimeBasedWidget::resizeEvent(event);
super::resizeEvent(event);
UpdateMinimumScale();
}
@@ -285,11 +286,11 @@ bool ViewerWidget::IsPlaying() const
return playback_speed_ != 0;
}
void ViewerWidget::ConnectViewerNode(Sequence *node, ColorManager* color_manager)
void ViewerWidget::ConnectViewerNode(ViewerOutput *node, ColorManager* color_manager)
{
override_color_manager_ = color_manager;
TimeBasedWidget::ConnectViewerNode(node);
super::ConnectViewerNode(node);
}
void ViewerWidget::SetColorMenuEnabled(bool enabled)
@@ -1053,7 +1054,7 @@ void ViewerWidget::SetSignalCursorColorEnabled(bool e)
void ViewerWidget::TimebaseChangedEvent(const rational &timebase)
{
TimeBasedWidget::TimebaseChangedEvent(timebase);
super::TimebaseChangedEvent(timebase);
controls_->SetTimebase(timebase);
+4 -4
View File
@@ -63,7 +63,7 @@ public:
bool IsPlaying() const;
void ConnectViewerNode(Sequence *node, ColorManager *color_manager = nullptr);
void ConnectViewerNode(ViewerOutput *node, ColorManager *color_manager = nullptr);
/**
* @brief Enable or disable the color management menu
@@ -153,9 +153,9 @@ protected:
virtual void TimebaseChangedEvent(const rational &) override;
virtual void TimeChangedEvent(const int64_t &) override;
virtual void ConnectNodeInternal(Sequence *) override;
virtual void DisconnectNodeInternal(Sequence *) override;
virtual void ConnectedNodeChanged(Sequence*n) override;
virtual void ConnectNodeInternal(ViewerOutput *) override;
virtual void DisconnectNodeInternal(ViewerOutput *) override;
virtual void ConnectedNodeChanged(ViewerOutput*n) override;
virtual void ScaleChangedEvent(const double& s) override;
+1 -1
View File
@@ -549,7 +549,7 @@ void MainWindow::RemoveProjectPanel(ProjectPanel *panel)
}
}
void MainWindow::TimelineFocused(Sequence* viewer)
void MainWindow::TimelineFocused(ViewerOutput* viewer)
{
sequence_viewer_panel_->ConnectViewerNode(viewer);
param_panel_->ConnectViewerNode(viewer);
+1 -1
View File
@@ -130,7 +130,7 @@ private:
void RemoveProjectPanel(ProjectPanel* panel);
void TimelineFocused(Sequence *viewer);
void TimelineFocused(ViewerOutput *viewer);
QByteArray premaximized_state_;