moved sequence params into node graph too

Reduces code by reusing more of the existing node infrastructure
to synchronize sequence parameters the render backend.
This commit is contained in:
itsmattkc
2021-02-18 13:20:23 +11:00
parent d7c5ac4b44
commit 4827782331
46 changed files with 1375 additions and 1394 deletions
+49
View File
@@ -25,6 +25,9 @@ extern "C" {
}
#include <QCoreApplication>
#include <QCryptographicHash>
#include "common/xmlutils.h"
namespace olive {
@@ -172,6 +175,52 @@ bool AudioParams::is_valid() const
&& format_ < kFormatCount);
}
QByteArray AudioParams::toBytes() const
{
QCryptographicHash hasher(QCryptographicHash::Sha1);
hasher.addData(reinterpret_cast<const char*>(&sample_rate_), sizeof(sample_rate_));
hasher.addData(reinterpret_cast<const char*>(&channel_layout_), sizeof(channel_layout_));
hasher.addData(reinterpret_cast<const char*>(&format_), sizeof(format_));
hasher.addData(reinterpret_cast<const char*>(&timebase_), sizeof(timebase_));
return hasher.result();
}
void AudioParams::Load(QXmlStreamReader *reader)
{
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("samplerate")) {
set_sample_rate(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("channellayout")) {
set_channel_layout(reader->readElementText().toULongLong());
} else if (reader->name() == QStringLiteral("format")) {
set_format(static_cast<AudioParams::Format>(reader->readElementText().toInt()));
} else if (reader->name() == QStringLiteral("enabled")) {
set_enabled(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("streamindex")) {
set_stream_index(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("duration")) {
set_duration(reader->readElementText().toLongLong());
} else if (reader->name() == QStringLiteral("timebase")) {
set_time_base(rational::fromString(reader->readElementText()));
} else {
reader->skipCurrentElement();
}
}
}
void AudioParams::Save(QXmlStreamWriter *writer) const
{
writer->writeTextElement(QStringLiteral("samplerate"), QString::number(sample_rate_));
writer->writeTextElement(QStringLiteral("channellayout"), QString::number(channel_layout_));
writer->writeTextElement(QStringLiteral("format"), QString::number(format_));
writer->writeTextElement(QStringLiteral("enabled"), QString::number(enabled_));
writer->writeTextElement(QStringLiteral("streamindex"), QString::number(stream_index_));
writer->writeTextElement(QStringLiteral("duration"), QString::number(duration_));
writer->writeTextElement(QStringLiteral("timebase"), timebase_.toString());
}
QString AudioParams::SampleRateToString(const int &sample_rate)
{
return QCoreApplication::translate("AudioParams", "%1 Hz").arg(sample_rate);
+82 -5
View File
@@ -23,6 +23,8 @@
#include <QAudioFormat>
#include <QtMath>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "common/rational.h"
@@ -63,6 +65,7 @@ public:
channel_layout_(0),
format_(kFormatInvalid)
{
set_default_footage_parameters();
}
AudioParams(const int& sample_rate, const uint64_t& channel_layout, const Format& format) :
@@ -70,28 +73,83 @@ public:
channel_layout_(channel_layout),
format_(format)
{
set_default_footage_parameters();
}
const int& sample_rate() const
int sample_rate() const
{
return sample_rate_;
}
const uint64_t& channel_layout() const
void set_sample_rate(int sample_rate)
{
sample_rate_ = sample_rate;
}
uint64_t channel_layout() const
{
return channel_layout_;
}
rational time_base() const
void set_channel_layout(uint64_t channel_layout)
{
return rational(1, sample_rate());
channel_layout_ = channel_layout;
}
const Format &format() const
rational time_base() const
{
if (timebase_.isNull()) {
return rational(1, sample_rate());
} else {
return timebase_;
}
}
void set_time_base(const rational& timebase)
{
timebase_ = timebase;
}
Format format() const
{
return format_;
}
void set_format(Format format)
{
format_ = format;
}
bool enabled() const
{
return enabled_;
}
void set_enabled(bool e)
{
enabled_ = e;
}
int stream_index() const
{
return stream_index_;
}
void set_stream_index(int s)
{
stream_index_ = s;
}
int64_t duration() const
{
return duration_;
}
void set_duration(int64_t duration)
{
duration_ = duration;
}
qint64 time_to_bytes(const double& time) const;
qint64 time_to_bytes(const rational& time) const;
qint64 time_to_samples(const double& time) const;
@@ -105,6 +163,12 @@ public:
int bits_per_sample() const;
bool is_valid() const;
QByteArray toBytes() const;
void Load(QXmlStreamReader* reader);
void Save(QXmlStreamWriter* writer) const;
bool operator==(const AudioParams& other) const;
bool operator!=(const AudioParams& other) const;
@@ -124,12 +188,25 @@ public:
static QString ChannelLayoutToString(const uint64_t &layout);
private:
void set_default_footage_parameters()
{
enabled_ = true;
stream_index_ = 0;
duration_ = 0;
}
int sample_rate_;
uint64_t channel_layout_;
Format format_;
// Footage-specific
bool enabled_;
int stream_index_;
int64_t duration_;
rational timebase_;
};
}
+58 -11
View File
@@ -28,28 +28,75 @@ namespace olive {
class FootageJob
{
public:
FootageJob() = default;
FootageJob(const Footage::StreamReference& ref, const TimeRange& range) :
footage_(ref),
range_(range)
FootageJob() :
type_(Stream::kUnknown)
{
}
const Footage::StreamReference& footage() const
FootageJob(const QString& decoder, const QString& filename, Stream::Type type) :
decoder_(decoder),
filename_(filename),
type_(type)
{
return footage_;
}
const TimeRange& range() const
const QString& decoder() const
{
return range_;
return decoder_;
}
const QString& filename() const
{
return filename_;
}
Stream::Type type() const
{
return type_;
}
const VideoParams& video_params() const
{
return video_params_;
}
void set_video_params(const VideoParams& p)
{
video_params_ = p;
}
const AudioParams& audio_params() const
{
return audio_params_;
}
void set_audio_params(const AudioParams& p)
{
audio_params_ = p;
}
const QString& cache_path() const
{
return cache_path_;
}
void set_cache_path(const QString& p)
{
cache_path_ = p;
}
private:
Footage::StreamReference footage_;
QString decoder_;
TimeRange range_;
QString filename_;
Stream::Type type_;
VideoParams video_params_;
AudioParams audio_params_;
QString cache_path_;
};
+2 -2
View File
@@ -437,8 +437,8 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
case NodeValue::kRational:
case NodeValue::kFont:
case NodeValue::kFile:
case NodeValue::kVideoStreamProperties:
case NodeValue::kAudioStreamProperties:
case NodeValue::kVideoParams:
case NodeValue::kAudioParams:
case NodeValue::kShaderJob:
case NodeValue::kSampleJob:
case NodeValue::kGenerateJob:
+2 -59
View File
@@ -65,7 +65,7 @@ void PreviewAutoCacher::GenerateHashes(Sequence *viewer, FrameHashCache* cache,
foreach (const rational& time, times) {
// See if hash already exists in disk cache
QByteArray hash = RenderManager::Hash(viewer->GetConnectedNode(ViewerOutput::kTextureInput), viewer->video_params(), time);
QByteArray hash = RenderManager::Hash(viewer->GetConnectedNode(Sequence::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());
@@ -264,12 +264,6 @@ void PreviewAutoCacher::ProcessUpdateQueue()
case QueuedJob::kValueChanged:
CopyValue(job.input);
break;
case QueuedJob::kVideoParamsChanged:
UpdateVideoParams();
break;
case QueuedJob::kAudioParamsChanged:
UpdateAudioParams();
break;
}
}
graph_update_queue_.clear();
@@ -330,16 +324,6 @@ void PreviewAutoCacher::CopyValue(const NodeInput &input)
Node::CopyValuesOfElement(input.node(), our_input, input.input(), input.element());
}
void PreviewAutoCacher::UpdateVideoParams()
{
copied_viewer_node_->set_video_params(viewer_node_->video_params());
}
void PreviewAutoCacher::UpdateAudioParams()
{
copied_viewer_node_->set_audio_params(viewer_node_->audio_params());
}
void PreviewAutoCacher::SetPlayhead(const rational &playhead)
{
cache_range_ = TimeRange(playhead - Config::Current()[QStringLiteral("DiskCacheBehind")].value<rational>(),
@@ -449,23 +433,6 @@ void PreviewAutoCacher::ValueChanged(const NodeInput &input)
graph_update_queue_.append({QueuedJob::kValueChanged, nullptr, input, NodeOutput()});
}
void PreviewAutoCacher::VideoParamsChanged()
{
// In case the user is pressing the mouse at this exact moment
IgnoreNextMouseButton();
graph_update_queue_.append({QueuedJob::kVideoParamsChanged, nullptr, NodeInput(), NodeOutput()});
ClearVideoQueue();
TryRender();
}
void PreviewAutoCacher::AudioParamsChanged()
{
graph_update_queue_.append({QueuedJob::kAudioParamsChanged, nullptr, NodeInput(), NodeOutput()});
ClearAudioQueue();
TryRender();
}
void PreviewAutoCacher::TryRender()
{
if (!graph_update_queue_.isEmpty()) {
@@ -639,16 +606,6 @@ void PreviewAutoCacher::SetViewerNode(Sequence *viewer_node)
disconnect(graph, &NodeGraph::ValueChanged, this, &PreviewAutoCacher::ValueChanged);
// Disconnect signal (will be a no-op if the signal was never connected)
disconnect(viewer_node_,
&ViewerOutput::VideoParamsChanged,
this,
&PreviewAutoCacher::VideoParamsChanged);
disconnect(viewer_node_,
&ViewerOutput::AudioParamsChanged,
this,
&PreviewAutoCacher::AudioParamsChanged);
disconnect(viewer_node_->video_frame_cache(),
&PlaybackCache::Invalidated,
this,
@@ -672,7 +629,7 @@ void PreviewAutoCacher::SetViewerNode(Sequence *viewer_node)
}
// Find copied viewer node
copied_viewer_node_ = static_cast<ViewerOutput*>(copy_map_.value(viewer_node_));
copied_viewer_node_ = static_cast<Sequence*>(copy_map_.value(viewer_node_));
// Copy parameters
copied_viewer_node_->set_video_params(viewer_node_->video_params());
@@ -698,20 +655,6 @@ void PreviewAutoCacher::SetViewerNode(Sequence *viewer_node)
invalidated_video_ = viewer_node_->video_frame_cache()->GetInvalidatedRanges();
invalidated_audio_ = viewer_node_->audio_playback_cache()->GetInvalidatedRanges();
// We begin an operation and never end it which prevents the copy from unnecessarily
// invalidating its own cache
copied_viewer_node_->BeginOperation();
connect(viewer_node_,
&ViewerOutput::VideoParamsChanged,
this,
&PreviewAutoCacher::VideoParamsChanged);
connect(viewer_node_,
&ViewerOutput::AudioParamsChanged,
this,
&PreviewAutoCacher::AudioParamsChanged);
connect(viewer_node_->video_frame_cache(),
&PlaybackCache::Invalidated,
this,
+1 -9
View File
@@ -111,8 +111,6 @@ private:
void AddEdge(const NodeOutput& output, const NodeInput& input);
void RemoveEdge(const NodeOutput& output, const NodeInput& input);
void CopyValue(const NodeInput& input);
void UpdateVideoParams();
void UpdateAudioParams();
class QueuedJob {
public:
@@ -121,9 +119,7 @@ private:
kNodeRemoved,
kEdgeAdded,
kEdgeRemoved,
kValueChanged,
kVideoParamsChanged,
kAudioParamsChanged
kValueChanged
};
Type type;
@@ -210,10 +206,6 @@ private slots:
void ValueChanged(const NodeInput& input);
void VideoParamsChanged();
void AudioParamsChanged();
void SingleFrameFinished();
/**
+26 -19
View File
@@ -262,7 +262,7 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const Track *track, const Tim
}
}
QVariant RenderProcessor::ProcessVideoFootage(const Footage::StreamReference &stream, const rational &input_time)
QVariant RenderProcessor::ProcessVideoFootage(const FootageJob &stream, const rational &input_time)
{
TexturePtr value = nullptr;
@@ -270,27 +270,34 @@ QVariant RenderProcessor::ProcessVideoFootage(const Footage::StreamReference &st
// and color managing them for every frame is a waste of time, so we implement a small cache here
// to optimize such a situation
const VideoParams& render_params = ticket_->property("vparam").value<VideoParams>();
VideoParams stream_params = stream.video_params();
VideoParams stream_data = stream.video_params();
ColorManager* color_manager = Node::ValueToPtr<ColorManager>(ticket_->property("colormanager"));
// See if we can make this divider larger (i.e. if the fooage is smaller)
int footage_divider = render_params.divider();
while (footage_divider > 1
&& VideoParams::GetScaledDimension(stream_params.width(), footage_divider-1) < render_params.effective_width()
&& VideoParams::GetScaledDimension(stream_params.height(), footage_divider-1) < render_params.effective_height()) {
&& VideoParams::GetScaledDimension(stream_data.width(), footage_divider-1) < render_params.effective_width()
&& VideoParams::GetScaledDimension(stream_data.height(), footage_divider-1) < render_params.effective_height()) {
footage_divider--;
}
Stream stream_data = stream.GetStream();
QString using_colorspace = stream_data.colorspace();
if (using_colorspace.isEmpty()) {
// FIXME:
qWarning() << "HAVEN'T GOTTEN DEFAULT INPUT COLORSPACE";
}
Decoder::CodecStream default_codec_stream(stream.filename(), stream_data.stream_index());
StillImageCache::EntryPtr want_entry = std::make_shared<StillImageCache::Entry>(
nullptr,
stream,
ColorProcessor::GenerateID(color_manager, stream.video_colorspace(), color_manager->GetReferenceColorSpace()),
default_codec_stream,
ColorProcessor::GenerateID(color_manager, using_colorspace, color_manager->GetReferenceColorSpace()),
stream_data.premultiplied_alpha(),
footage_divider,
(stream_data.video_type() == Stream::kVideoTypeStill) ? 0 : input_time,
(stream_data.video_type() == VideoParams::kVideoTypeStill) ? 0 : input_time,
true);
bool found_existing = false;
@@ -327,31 +334,31 @@ QVariant RenderProcessor::ProcessVideoFootage(const Footage::StreamReference &st
still_image_cache_->mutex()->unlock();
QString decoder_id = stream.footage()->decoder();
QString decoder_id = stream.decoder();
DecoderPtr decoder = nullptr;
if (stream_data.video_type() == Stream::kVideoTypeVideo) {
decoder = ResolveDecoderFromInput(decoder_id, Decoder::GetCodecStreamFromStreamReference(stream));
if (stream_data.video_type() == VideoParams::kVideoTypeVideo) {
decoder = ResolveDecoderFromInput(decoder_id, default_codec_stream);
} else {
// Since image sequences involve multiple files, we don't engage the decoder cache
decoder = Decoder::CreateFromID(decoder_id);
QString frame_filename;
if (stream_data.video_type() == Stream::kVideoTypeImageSequence) {
int64_t frame_number = stream.GetTimeInTimebaseUnits(input_time);
if (stream_data.video_type() == VideoParams::kVideoTypeImageSequence) {
int64_t frame_number = stream_data.get_time_in_timebase_units(input_time);
frame_filename = Decoder::TransformImageSequenceFileName(stream.filename(), frame_number);
} else {
frame_filename = stream.filename();
}
// Decoder will close automatically since it's a stream_ptr
decoder->Open(Decoder::CodecStream(frame_filename, stream.index()));
decoder->Open(Decoder::CodecStream(frame_filename, stream_data.stream_index()));
}
if (decoder) {
FramePtr frame = decoder->RetrieveVideo((stream_data.video_type() == Stream::kVideoTypeVideo) ? input_time : Decoder::kAnyTimecode, footage_divider);
FramePtr frame = decoder->RetrieveVideo((stream_data.video_type() == VideoParams::kVideoTypeVideo) ? input_time : Decoder::kAnyTimecode, footage_divider);
if (frame) {
// Return a texture from the derived class
@@ -368,7 +375,7 @@ QVariant RenderProcessor::ProcessVideoFootage(const Footage::StreamReference &st
value = render_ctx_->CreateTexture(managed_params);
ColorProcessorPtr processor = ColorProcessor::Create(color_manager,
stream.video_colorspace(),
using_colorspace,
color_manager->GetReferenceColorSpace());
render_ctx_->BlitColorManaged(processor, unmanaged_texture,
@@ -391,17 +398,17 @@ QVariant RenderProcessor::ProcessVideoFootage(const Footage::StreamReference &st
return QVariant::fromValue(value);
}
QVariant RenderProcessor::ProcessAudioFootage(const Footage::StreamReference &stream, const TimeRange &input_time)
QVariant RenderProcessor::ProcessAudioFootage(const FootageJob &stream, const TimeRange &input_time)
{
QVariant value;
DecoderPtr decoder = ResolveDecoderFromInput(stream.footage()->decoder(), Decoder::GetCodecStreamFromStreamReference(stream));
DecoderPtr decoder = ResolveDecoderFromInput(stream.decoder(), Decoder::CodecStream(stream.filename(), stream.audio_params().stream_index()));
if (decoder) {
const AudioParams& audio_params = ticket_->property("aparam").value<AudioParams>();
SampleBufferPtr frame = decoder->RetrieveAudio(input_time, audio_params,
stream.footage()->project()->cache_path(),
stream.cache_path(),
&IsCancelled());
if (frame) {
+2 -2
View File
@@ -43,9 +43,9 @@ public:
protected:
virtual NodeValueTable GenerateBlockTable(const Track *track, const TimeRange &range) override;
virtual QVariant ProcessVideoFootage(const Footage::StreamReference &stream, const rational &input_time) override;
virtual QVariant ProcessVideoFootage(const FootageJob &stream, const rational &input_time) override;
virtual QVariant ProcessAudioFootage(const Footage::StreamReference &stream, const TimeRange &input_time) override;
virtual QVariant ProcessAudioFootage(const FootageJob &stream, const TimeRange &input_time) override;
virtual QVariant ProcessShader(const Node *node, const TimeRange &range, const ShaderJob& job) override;
+3 -2
View File
@@ -4,6 +4,7 @@
#include <QHash>
#include <QWaitCondition>
#include "codec/decoder.h"
#include "common/rational.h"
#include "project/item/footage/footage.h"
#include "render/texture.h"
@@ -14,7 +15,7 @@ class StillImageCache
{
public:
struct Entry {
Entry(TexturePtr t, const Footage::StreamReference& s, const QString& cs, bool a, int d, const rational& i, bool w)
Entry(TexturePtr t, const Decoder::CodecStream& s, const QString& cs, bool a, int d, const rational& i, bool w)
{
texture = t;
stream = s;
@@ -26,7 +27,7 @@ public:
}
TexturePtr texture;
Footage::StreamReference stream;
Decoder::CodecStream stream;
QString colorspace;
bool alpha_is_associated;
int divider;
+114 -1
View File
@@ -67,8 +67,10 @@ VideoParams::VideoParams() :
depth_(0),
format_(kFormatInvalid),
channel_count_(0),
interlacing_(Interlacing::kInterlaceNone)
interlacing_(Interlacing::kInterlaceNone),
divider_(1)
{
set_defaults_for_footage();
}
VideoParams::VideoParams(int width, int height, Format format, int nb_channels, const rational& pixel_aspect_ratio, Interlacing interlacing, int divider) :
@@ -83,6 +85,7 @@ VideoParams::VideoParams(int width, int height, Format format, int nb_channels,
{
calculate_effective_size();
validate_pixel_aspect_ratio();
set_defaults_for_footage();
}
VideoParams::VideoParams(int width, int height, int depth, Format format, int nb_channels, const rational &pixel_aspect_ratio, VideoParams::Interlacing interlacing, int divider) :
@@ -97,6 +100,7 @@ VideoParams::VideoParams(int width, int height, int depth, Format format, int nb
{
calculate_effective_size();
validate_pixel_aspect_ratio();
set_defaults_for_footage();
}
VideoParams::VideoParams(int width, int height, const rational &time_base, Format format, int nb_channels, const rational& pixel_aspect_ratio, Interlacing interlacing, int divider) :
@@ -112,6 +116,7 @@ VideoParams::VideoParams(int width, int height, const rational &time_base, Forma
{
calculate_effective_size();
validate_pixel_aspect_ratio();
set_defaults_for_footage();
}
int VideoParams::generate_auto_divider(qint64 width, qint64 height)
@@ -237,6 +242,16 @@ void VideoParams::validate_pixel_aspect_ratio()
}
}
void VideoParams::set_defaults_for_footage()
{
enabled_ = true;
stream_index_ = 0;
video_type_ = kVideoTypeVideo;
start_time_ = 0;
duration_ = 0;
premultiplied_alpha_ = false;
}
bool VideoParams::is_valid() const
{
return (width() > 0
@@ -280,4 +295,102 @@ int VideoParams::GetScaledDimension(int dim, int divider)
return dim / divider;
}
QByteArray VideoParams::toBytes() const
{
QCryptographicHash hasher(QCryptographicHash::Sha1);
hasher.addData(reinterpret_cast<const char*>(&width_), sizeof(width_));
hasher.addData(reinterpret_cast<const char*>(&height_), sizeof(height_));
hasher.addData(reinterpret_cast<const char*>(&depth_), sizeof(depth_));
hasher.addData(reinterpret_cast<const char*>(&time_base_), sizeof(time_base_));
hasher.addData(reinterpret_cast<const char*>(&format_), sizeof(format_));
hasher.addData(reinterpret_cast<const char*>(&channel_count_), sizeof(channel_count_));
hasher.addData(reinterpret_cast<const char*>(&pixel_aspect_ratio_), sizeof(pixel_aspect_ratio_));
hasher.addData(reinterpret_cast<const char*>(&interlacing_), sizeof(interlacing_));
hasher.addData(reinterpret_cast<const char*>(&divider_), sizeof(divider_));
hasher.addData(reinterpret_cast<const char*>(&enabled_), sizeof(enabled_));
hasher.addData(reinterpret_cast<const char*>(&stream_index_), sizeof(stream_index_));
hasher.addData(reinterpret_cast<const char*>(&video_type_), sizeof(video_type_));
hasher.addData(reinterpret_cast<const char*>(&frame_rate_), sizeof(frame_rate_));
hasher.addData(reinterpret_cast<const char*>(&start_time_), sizeof(start_time_));
hasher.addData(reinterpret_cast<const char*>(&duration_), sizeof(duration_));
hasher.addData(reinterpret_cast<const char*>(&premultiplied_alpha_), sizeof(premultiplied_alpha_));
hasher.addData(colorspace_.toUtf8());
return hasher.result();
}
int64_t VideoParams::get_time_in_timebase_units(const rational &time) const
{
if (time_base_.isNull()) {
return AV_NOPTS_VALUE;
}
return Timecode::time_to_timestamp(time, time_base_) + start_time_;
}
void VideoParams::Load(QXmlStreamReader *reader)
{
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("width")) {
set_width(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("height")) {
set_height(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("depth")) {
set_depth(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("timebase")) {
set_time_base(rational::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("format")) {
set_format(static_cast<VideoParams::Format>(reader->readElementText().toInt()));
} else if (reader->name() == QStringLiteral("channelcount")) {
set_channel_count(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("pixelaspectratio")) {
set_pixel_aspect_ratio(rational::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("interlacing")) {
set_interlacing(static_cast<VideoParams::Interlacing>(reader->readElementText().toInt()));
} else if (reader->name() == QStringLiteral("divider")) {
set_divider(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("enabled")) {
set_enabled(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("streamindex")) {
set_stream_index(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("videotype")) {
set_video_type(static_cast<VideoParams::Type>(reader->readElementText().toInt()));
} else if (reader->name() == QStringLiteral("framerate")) {
set_frame_rate(rational::fromString(reader->readElementText()));
} else if (reader->name() == QStringLiteral("starttime")) {
set_start_time(reader->readElementText().toLongLong());
} else if (reader->name() == QStringLiteral("duration")) {
set_duration(reader->readElementText().toLongLong());
} else if (reader->name() == QStringLiteral("premultipliedalpha")) {
set_premultiplied_alpha(reader->readElementText().toInt());
} else if (reader->name() == QStringLiteral("colorspace")) {
set_colorspace(reader->readElementText());
} else {
reader->skipCurrentElement();
}
}
}
void VideoParams::Save(QXmlStreamWriter *writer) const
{
writer->writeTextElement(QStringLiteral("width"), QString::number(width_));
writer->writeTextElement(QStringLiteral("height"), QString::number(height_));
writer->writeTextElement(QStringLiteral("depth"), QString::number(depth_));
writer->writeTextElement(QStringLiteral("timebase"), time_base_.toString());
writer->writeTextElement(QStringLiteral("format"), QString::number(format_));
writer->writeTextElement(QStringLiteral("channelcount"), QString::number(channel_count_));
writer->writeTextElement(QStringLiteral("pixelaspectratio"), pixel_aspect_ratio_.toString());
writer->writeTextElement(QStringLiteral("interlacing"), QString::number(interlacing_));
writer->writeTextElement(QStringLiteral("divider"), QString::number(divider_));
writer->writeTextElement(QStringLiteral("enabled"), QString::number(enabled_));
writer->writeTextElement(QStringLiteral("streamindex"), QString::number(stream_index_));
writer->writeTextElement(QStringLiteral("videotype"), QString::number(video_type_));
writer->writeTextElement(QStringLiteral("framerate"), frame_rate_.toString());
writer->writeTextElement(QStringLiteral("starttime"), QString::number(start_time_));
writer->writeTextElement(QStringLiteral("duration"), QString::number(duration_));
writer->writeTextElement(QStringLiteral("premultipliedalpha"), QString::number(premultiplied_alpha_));
writer->writeTextElement(QStringLiteral("colorspace"), colorspace_);
}
}
+111
View File
@@ -21,6 +21,9 @@
#ifndef VIDEOPARAMS_H
#define VIDEOPARAMS_H
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "common/rational.h"
#include "rendermodes.h"
@@ -57,6 +60,12 @@ public:
kInterlacedBottomFirst
};
enum Type {
kVideoTypeVideo,
kVideoTypeStill,
kVideoTypeImageSequence
};
VideoParams();
VideoParams(int width, int height, Format format, int nb_channels,
const rational& pixel_aspect_ratio = 1,
@@ -239,11 +248,101 @@ public:
static int GetScaledDimension(int dim, int divider);
QByteArray toBytes() const;
bool enabled() const
{
return enabled_;
}
void set_enabled(bool e)
{
enabled_ = e;
}
int stream_index() const
{
return stream_index_;
}
void set_stream_index(int s)
{
stream_index_ = s;
}
Type video_type() const
{
return video_type_;
}
void set_video_type(Type t)
{
video_type_ = t;
}
const rational& frame_rate() const
{
return frame_rate_;
}
void set_frame_rate(const rational& frame_rate)
{
frame_rate_ = frame_rate;
}
int64_t start_time() const
{
return start_time_;
}
void set_start_time(int64_t start_time)
{
start_time_ = start_time;
}
int64_t duration() const
{
return duration_;
}
void set_duration(int64_t duration)
{
duration_ = duration;
}
bool premultiplied_alpha() const
{
return premultiplied_alpha_;
}
void set_premultiplied_alpha(bool premultiplied_alpha)
{
premultiplied_alpha_ = premultiplied_alpha;
}
const QString& colorspace() const
{
return colorspace_;
}
void set_colorspace(const QString& c)
{
colorspace_ = c;
}
int64_t get_time_in_timebase_units(const rational& time) const;
void Load(QXmlStreamReader* reader);
void Save(QXmlStreamWriter* writer) const;
private:
void calculate_effective_size();
void validate_pixel_aspect_ratio();
void set_defaults_for_footage();
int width_;
int height_;
int depth_;
@@ -258,9 +357,21 @@ private:
Interlacing interlacing_;
int divider_;
// Cached values
int effective_width_;
int effective_height_;
int effective_depth_;
bool enabled_;
int stream_index_;
Type video_type_;
rational frame_rate_;
int64_t start_time_;
int64_t duration_;
bool premultiplied_alpha_;
QString colorspace_;
};
}