various: added hooks so that various lengthy functions could be cancelled from another thread

This commit is contained in:
itsmattkc
2020-02-17 02:10:12 +11:00
parent fd49b6eb55
commit 22046535ca
25 changed files with 208 additions and 80 deletions
+10 -6
View File
@@ -57,12 +57,12 @@ void Decoder::set_stream(StreamPtr fs)
stream_ = fs;
}
FramePtr Decoder::RetrieveVideo(const rational &/*timecode*/)
FramePtr Decoder::RetrieveVideo(const rational &/*timecode*/, const QAtomicInt* cancelled)
{
return nullptr;
}
FramePtr Decoder::RetrieveAudio(const rational &/*timecode*/, const rational &/*length*/, const AudioRenderingParams &/*params*/)
FramePtr Decoder::RetrieveAudio(const rational &/*timecode*/, const rational &/*length*/, const AudioRenderingParams &/*params*/, const QAtomicInt* cancelled)
{
return nullptr;
}
@@ -93,7 +93,7 @@ QVector<DecoderPtr> ReceiveListOfAllDecoders() {
return decoders;
}
bool Decoder::ProbeMedia(Footage *f)
bool Decoder::ProbeMedia(Footage *f, const QAtomicInt* cancelled)
{
// Check for a valid filename
if (f->filename().isEmpty()) {
@@ -116,9 +116,13 @@ bool Decoder::ProbeMedia(Footage *f)
// Pass Footage through each Decoder's probe function
for (int i=0;i<decoder_list.size();i++) {
if (cancelled && *cancelled) {
return false;
}
DecoderPtr decoder = decoder_list.at(i);
if (decoder->Probe(f)) {
if (decoder->Probe(f, cancelled)) {
// We found a Decoder, so we can set this media as valid
f->set_status(Footage::kReady);
@@ -168,13 +172,13 @@ DecoderPtr Decoder::CreateFromID(const QString &id)
return nullptr;
}
void Decoder::Conform(const AudioRenderingParams &params)
void Decoder::Conform(const AudioRenderingParams &params, const QAtomicInt* cancelled)
{
Q_UNUSED(params)
qCritical() << "Conform called on an audio decoder that does not have a handler for it:" << id();
abort();
}
void Decoder::Index()
void Decoder::Index(const QAtomicInt *cancelled)
{
}
+7 -7
View File
@@ -91,7 +91,7 @@ public:
* TRUE if the Decoder was able to decode this file. FALSE if not. This function should have filled the Footage
* object with metadata if it returns TRUE. Otherwise, the Footage object should be untouched.
*/
virtual bool Probe(Footage* f) = 0;
virtual bool Probe(Footage* f, const QAtomicInt* cancelled) = 0;
/**
* @brief Open media/allocate memory
@@ -127,7 +127,7 @@ public:
* A FramePtr of valid data at this timecode or nullptr if there was nothing to retrieve at the provided timecode or
* the media could not be opened.
*/
virtual FramePtr RetrieveVideo(const rational& timecode);
virtual FramePtr RetrieveVideo(const rational& timecode, const QAtomicInt* cancelled);
/**
* @brief Retrieve video frame
@@ -153,7 +153,7 @@ public:
* A FramePtr of valid data at this timecode of the requested length or nullptr if there was nothing to retrieve at
* the provided timecode or the media could not be opened.
*/
virtual FramePtr RetrieveAudio(const rational& timecode, const rational& length, const AudioRenderingParams& params);
virtual FramePtr RetrieveAudio(const rational& timecode, const rational& length, const AudioRenderingParams& params, const QAtomicInt* cancelled);
virtual bool SupportsVideo();
virtual bool SupportsAudio();
@@ -174,7 +174,7 @@ public:
*
* Used to determine which frame will be served at a given time, useful for caching.
*/
virtual int64_t GetTimestampFromTime(const rational& time) = 0;
virtual int64_t GetTimestampFromTime(const rational& time, const QAtomicInt* cancelled) = 0;
/**
* @brief Try to probe a Footage file by passing it through all available Decoders
@@ -195,7 +195,7 @@ public:
*
* TRUE if a Decoder was successfully able to parse and probe this file. FALSE if not.
*/
static bool ProbeMedia(Footage* f);
static bool ProbeMedia(Footage* f, const QAtomicInt *cancelled);
/**
* @brief Create a Decoder instance using a Decoder ID
@@ -217,7 +217,7 @@ public:
* All audio decoders must override this. It's not pure since video decoders don't need to use this, but default
* behavior will abort since it should never be called.
*/
virtual void Conform(const AudioRenderingParams& params);
virtual void Conform(const AudioRenderingParams& params, const QAtomicInt* cancelled);
/**
* @brief Create an index for this media
@@ -228,7 +228,7 @@ public:
* Indexing is slow so it's recommended to do it in a background thread. Index() must be called while the Decoder is
* open, and does not automatically call Open() and Close() the Decoder. The caller must call thse manually.
*/
virtual void Index();
virtual void Index(const QAtomicInt* cancelled);
protected:
bool open_;
+53 -20
View File
@@ -192,7 +192,7 @@ bool FFmpegDecoder::Open()
return true;
}
FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode)
FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode, const QAtomicInt* cancelled)
{
if (!open_ && !Open()) {
return nullptr;
@@ -203,7 +203,7 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode)
}
// Convert timecode to AVStream timebase
int64_t target_ts = GetTimestampFromTime(timecode);
int64_t target_ts = GetTimestampFromTime(timecode, cancelled);
if (target_ts < 0) {
Error(QStringLiteral("Index failed to produce a valid timestamp"));
@@ -318,7 +318,7 @@ FramePtr FFmpegDecoder::RetrieveVideo(const rational &timecode)
return nullptr;
}
FramePtr FFmpegDecoder::RetrieveAudio(const rational &timecode, const rational &length, const AudioRenderingParams &params)
FramePtr FFmpegDecoder::RetrieveAudio(const rational &timecode, const rational &length, const AudioRenderingParams &params, const QAtomicInt* cancelled)
{
if (!open_ && !Open()) {
return nullptr;
@@ -328,9 +328,9 @@ FramePtr FFmpegDecoder::RetrieveAudio(const rational &timecode, const rational &
return nullptr;
}
Index();
Index(cancelled);
Conform(params);
Conform(params, cancelled);
WaveInput input(GetConformedFilename(params));
@@ -395,7 +395,7 @@ QString FFmpegDecoder::id()
return "ffmpeg";
}
int64_t FFmpegDecoder::GetTimestampFromTime(const rational &time)
int64_t FFmpegDecoder::GetTimestampFromTime(const rational &time, const QAtomicInt* cancelled)
{
if (!open_ && !Open()) {
return -1;
@@ -408,19 +408,19 @@ int64_t FFmpegDecoder::GetTimestampFromTime(const rational &time)
target_ts += avstream_->start_time;
// Find closest actual timebase in the file
target_ts = GetClosestTimestampInIndex(target_ts);
target_ts = GetClosestTimestampInIndex(target_ts, cancelled);
return target_ts;
}
void FFmpegDecoder::Conform(const AudioRenderingParams &params)
void FFmpegDecoder::Conform(const AudioRenderingParams &params, const QAtomicInt* cancelled)
{
if (avstream_->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
// Nothing to be done
return;
}
Index();
Index(cancelled);
// Get indexed WAV file
WaveInput input(GetIndexFilename());
@@ -470,6 +470,10 @@ void FFmpegDecoder::Conform(const AudioRenderingParams &params)
int input_buffer_sz = input.params().time_to_bytes(1);
while (!input.at_end()) {
if (cancelled && *cancelled) {
break;
}
// Read up to one second of audio from WAV file
QByteArray read_samples = input.read(input_buffer_sz);
@@ -486,6 +490,11 @@ void FFmpegDecoder::Conform(const AudioRenderingParams &params)
swr_free(&resampler);
conformed_output.close();
input.close();
// If we cancelled, the conform didn't finish so remove it
if (cancelled && *cancelled) {
QFile(conformed_fn).remove();
}
} else {
qWarning() << "Failed to conform file:" << stream()->footage()->filename();
}
@@ -531,7 +540,7 @@ void FFmpegDecoder::ConformInternal(SwrContext* resampler, WaveOutput* output, c
output->write(out_samples);
}
bool FFmpegDecoder::Probe(Footage *f)
bool FFmpegDecoder::Probe(Footage *f, const QAtomicInt* cancelled)
{
if (open_) {
qWarning() << "Probe must be called while the Decoder is closed";
@@ -648,7 +657,7 @@ bool FFmpegDecoder::Probe(Footage *f)
Open();
// Use index to find duration
Index();
Index(cancelled);
// Use last frame index as the duration
// FIXME: Does this skip the last frame?
@@ -688,7 +697,7 @@ void FFmpegDecoder::Error(const QString &s)
Close();
}
void FFmpegDecoder::Index()
void FFmpegDecoder::Index(const QAtomicInt* cancelled)
{
if (!open_) {
qWarning() << "Indexing function tried to run while decoder was closed";
@@ -699,11 +708,11 @@ void FFmpegDecoder::Index()
if (stream()->type() == Stream::kVideo) {
ValidateVideoIndex();
ValidateVideoIndex(cancelled);
} else if (stream()->type() == Stream::kAudio) {
if (!QFileInfo::exists(GetIndexFilename())) {
UnconditionalAudioIndex(pkt_, frame_);
UnconditionalAudioIndex(pkt_, frame_, cancelled);
}
}
}
@@ -746,7 +755,7 @@ QString FFmpegDecoder::GetConformedFilename(const AudioRenderingParams &params)
return index_fn;
}
void FFmpegDecoder::UnconditionalAudioIndex(AVPacket *pkt, AVFrame *frame)
void FFmpegDecoder::UnconditionalAudioIndex(AVPacket *pkt, AVFrame *frame, const QAtomicInt* cancelled)
{
// Iterate through each audio frame and extract the PCM data
@@ -792,6 +801,11 @@ void FFmpegDecoder::UnconditionalAudioIndex(AVPacket *pkt, AVFrame *frame)
if (wave_out.open()) {
while (true) {
// Check if we have a `cancelled` ptr and its value
if (cancelled && *cancelled) {
break;
}
ret = GetFrame(pkt, frame);
if (ret < 0) {
@@ -837,6 +851,11 @@ void FFmpegDecoder::UnconditionalAudioIndex(AVPacket *pkt, AVFrame *frame)
}
wave_out.close();
if (cancelled && *cancelled) {
// Audio index didn't complete, delete it
QFile(GetIndexFilename()).remove();
}
} else {
qWarning() << "Failed to open WAVE output for indexing";
}
@@ -848,7 +867,7 @@ void FFmpegDecoder::UnconditionalAudioIndex(AVPacket *pkt, AVFrame *frame)
Seek(0);
}
void FFmpegDecoder::UnconditionalVideoIndex(AVPacket* pkt, AVFrame* frame)
void FFmpegDecoder::UnconditionalVideoIndex(AVPacket* pkt, AVFrame* frame, const QAtomicInt* cancelled)
{
VideoStreamPtr video_stream = std::static_pointer_cast<VideoStream>(stream());
@@ -863,6 +882,11 @@ void FFmpegDecoder::UnconditionalVideoIndex(AVPacket* pkt, AVFrame* frame)
int ret;
while (true) {
// Check if we have a `cancelled` ptr and its value
if (cancelled && *cancelled) {
break;
}
ret = GetFrame(pkt, frame);
if (ret >= 0) {
@@ -875,12 +899,17 @@ void FFmpegDecoder::UnconditionalVideoIndex(AVPacket* pkt, AVFrame* frame)
}
}
// Check if we have a `cancelled` ptr and its value
if (cancelled && *cancelled) {
video_stream->clear_frame_index();
} else {
video_stream->append_frame_index(VideoStream::kEndTimestamp);
// Save index to file
if (!video_stream->save_frame_index(GetIndexFilename())) {
qWarning() << QStringLiteral("Failed to save index for %1").arg(stream()->footage()->filename());
}
}
Seek(0);
}
@@ -930,7 +959,7 @@ int FFmpegDecoder::GetFrame(AVPacket *pkt, AVFrame *frame)
return ret;
}
int64_t FFmpegDecoder::GetClosestTimestampInIndex(const int64_t &ts)
int64_t FFmpegDecoder::GetClosestTimestampInIndex(const int64_t &ts, const QAtomicInt* cancelled)
{
VideoStreamPtr video_stream = std::static_pointer_cast<VideoStream>(stream());
@@ -942,7 +971,7 @@ int64_t FFmpegDecoder::GetClosestTimestampInIndex(const int64_t &ts)
// If not, check if the frame index has been populated
if (!video_stream->is_frame_index_ready()) {
// If not, make a frame index
ValidateVideoIndex();
ValidateVideoIndex(cancelled);
}
video_stream->index_process_lock()->unlock();
@@ -954,6 +983,10 @@ int64_t FFmpegDecoder::GetClosestTimestampInIndex(const int64_t &ts)
int64_t closest_ts = -1;
do {
if (cancelled && *cancelled) {
return -1;
}
if (index_is_being_created && video_stream->index_process_lock()->tryLock()) {
index_is_being_created = false;
video_stream->index_process_lock()->unlock();
@@ -969,7 +1002,7 @@ int64_t FFmpegDecoder::GetClosestTimestampInIndex(const int64_t &ts)
return closest_ts;
}
void FFmpegDecoder::ValidateVideoIndex()
void FFmpegDecoder::ValidateVideoIndex(const QAtomicInt* cancelled)
{
VideoStreamPtr video_stream = std::static_pointer_cast<VideoStream>(stream());
@@ -981,7 +1014,7 @@ void FFmpegDecoder::ValidateVideoIndex()
// Reset state
Seek(0);
UnconditionalVideoIndex(pkt_, frame_);
UnconditionalVideoIndex(pkt_, frame_, cancelled);
Seek(0);
}
+10 -10
View File
@@ -47,25 +47,25 @@ public:
// Destructor
virtual ~FFmpegDecoder() override;
virtual bool Probe(Footage *f) override;
virtual bool Probe(Footage *f, const QAtomicInt *cancelled) override;
virtual bool Open() override;
virtual FramePtr RetrieveVideo(const rational &timecode) override;
virtual FramePtr RetrieveAudio(const rational &timecode, const rational &length, const AudioRenderingParams& params) override;
virtual FramePtr RetrieveVideo(const rational &timecode, const QAtomicInt *cancelled) override;
virtual FramePtr RetrieveAudio(const rational &timecode, const rational &length, const AudioRenderingParams& params, const QAtomicInt *cancelled) override;
virtual void Close() override;
virtual QString id() override;
virtual int64_t GetTimestampFromTime(const rational& time) override;
virtual int64_t GetTimestampFromTime(const rational& time, const QAtomicInt *cancelled) override;
virtual void Conform(const AudioRenderingParams& params) override;
virtual void Conform(const AudioRenderingParams& params, const QAtomicInt *cancelled) override;
virtual bool SupportsVideo() override;
virtual bool SupportsAudio() override;
void SetMultithreading(bool e);
virtual void Index() override;
virtual void Index(const QAtomicInt *cancelled) override;
private:
void ConformInternal(SwrContext *resampler, WaveOutput *output, const char *in_data, int in_sample_count);
@@ -110,12 +110,12 @@ private:
*/
QString GetConformedFilename(const AudioRenderingParams &params);
void UnconditionalAudioIndex(AVPacket* pkt, AVFrame* frame);
void UnconditionalVideoIndex(AVPacket* pkt, AVFrame* frame);
void UnconditionalAudioIndex(AVPacket* pkt, AVFrame* frame, const QAtomicInt* cancelled);
void UnconditionalVideoIndex(AVPacket* pkt, AVFrame* frame, const QAtomicInt* cancelled);
int64_t GetClosestTimestampInIndex(const int64_t& ts);
int64_t GetClosestTimestampInIndex(const int64_t& ts, const QAtomicInt *cancelled);
void ValidateVideoIndex();
void ValidateVideoIndex(const QAtomicInt* cancelled);
void Seek(int64_t timestamp);
+3 -3
View File
@@ -38,7 +38,7 @@ QString OIIODecoder::id()
return "oiio";
}
bool OIIODecoder::Probe(Footage *f)
bool OIIODecoder::Probe(Footage *f, const QAtomicInt *cancelled)
{
// We prioritize OIIO over FFmpeg to pick up still images more effectively, but some OIIO decoders (notably OpenJPEG)
// will segfault entirely if given unexpected data (an MPEG-4 for instance). To workaround this issue, we use OIIO's
@@ -133,7 +133,7 @@ bool OIIODecoder::Open()
return true;
}
FramePtr OIIODecoder::RetrieveVideo(const rational &timecode)
FramePtr OIIODecoder::RetrieveVideo(const rational &timecode, const QAtomicInt *cancelled)
{
if (!open_ && !Open()) {
return nullptr;
@@ -174,7 +174,7 @@ void OIIODecoder::Close()
frame_ = nullptr;
}
int64_t OIIODecoder::GetTimestampFromTime(const rational &time)
int64_t OIIODecoder::GetTimestampFromTime(const rational &time, const QAtomicInt *cancelled)
{
Q_UNUSED(time)
+3 -3
View File
@@ -33,15 +33,15 @@ public:
virtual QString id() override;
virtual bool Probe(Footage *f) override;
virtual bool Probe(Footage *f, const QAtomicInt* cancelled) override;
virtual bool Open() override;
virtual FramePtr RetrieveVideo(const rational &timecode) override;
virtual FramePtr RetrieveVideo(const rational &timecode, const QAtomicInt* cancelled) override;
virtual void Close() override;
virtual int64_t GetTimestampFromTime(const rational &time) override;
virtual int64_t GetTimestampFromTime(const rational &time, const QAtomicInt* cancelled) override;
virtual bool SupportsVideo() override;
+1
View File
@@ -18,6 +18,7 @@ set(OLIVE_SOURCES
${OLIVE_SOURCES}
common/bezier.h
common/bezier.cpp
common/cancelableobject.h
common/channellayout.h
common/clamp.h
common/constructors.h
+26
View File
@@ -0,0 +1,26 @@
#ifndef CANCELABLEOBJECT_H
#define CANCELABLEOBJECT_H
#include <QAtomicInt>
class CancelableObject {
public:
CancelableObject() :
cancelled_(false)
{
}
void Cancel() {
cancelled_ = true;
}
const QAtomicInt& IsCancelled() const {
return cancelled_;
}
private:
QAtomicInt cancelled_;
};
#endif // CANCELABLEOBJECT_H
+31 -3
View File
@@ -86,21 +86,33 @@ QString NodeInput::name()
return NodeParam::name();
}
void NodeInput::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections)
void NodeInput::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections, const QAtomicInt *cancelled)
{
XMLAttributeLoop(reader, attr) {
if (cancelled && *cancelled) {
return;
}
if (attr.name() == "keyframing") {
set_is_keyframing(attr.value() == "1");
}
}
XMLReadLoop(reader, "input") {
if (cancelled && *cancelled) {
return;
}
if (reader->isStartElement()) {
if (reader->name() == "standard") {
// Load standard value
int val_index = 0;
XMLReadLoop(reader, "standard") {
if (cancelled && *cancelled) {
return;
}
if (reader->isStartElement() && reader->name() == "value") {
reader->readNext();
@@ -119,8 +131,16 @@ void NodeInput::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& par
int track = 0;
XMLReadLoop(reader, "keyframes") {
if (cancelled && *cancelled) {
return;
}
if (reader->isStartElement() && reader->name() == "track") {
XMLReadLoop(reader, "track") {
if (cancelled && *cancelled) {
return;
}
if (reader->name() == "key") {
rational key_time;
NodeKeyframe::Type key_type;
@@ -129,6 +149,10 @@ void NodeInput::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& par
QPointF key_out_handle;
XMLAttributeLoop(reader, attr) {
if (cancelled && *cancelled) {
return;
}
if (attr.name() == "time") {
key_time = rational::fromString(attr.value().toString());
} else if (attr.name() == "type") {
@@ -161,6 +185,10 @@ void NodeInput::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& par
}
} else if (reader->name() == "connections") {
XMLReadLoop(reader, "connections") {
if (cancelled && *cancelled) {
return;
}
if (reader->isStartElement() && reader->name() == "connection") {
reader->readNext();
@@ -168,7 +196,7 @@ void NodeInput::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& par
}
}
} else {
LoadInternal(reader, param_ptrs, input_connections, footage_connections);
LoadInternal(reader, param_ptrs, input_connections, footage_connections, cancelled);
}
}
}
@@ -242,7 +270,7 @@ const NodeParam::DataType &NodeInput::data_type() const
return data_type_;
}
void NodeInput::LoadInternal(QXmlStreamReader*, QHash<quintptr, NodeOutput *>&, QList<SerializedConnection>&, QList<FootageConnection>&)
void NodeInput::LoadInternal(QXmlStreamReader*, QHash<quintptr, NodeOutput *>&, QList<SerializedConnection>&, QList<FootageConnection>&, const QAtomicInt*)
{
}
+2 -2
View File
@@ -54,7 +54,7 @@ public:
virtual QString name() override;
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections) override;
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections, const QAtomicInt* cancelled) override;
virtual void Save(QXmlStreamWriter* writer) const override;
@@ -243,7 +243,7 @@ signals:
void KeyframeRemoved(NodeKeyframePtr key);
protected:
virtual void LoadInternal(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections);
virtual void LoadInternal(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections, const QAtomicInt* cancelled);
virtual void SaveInternal(QXmlStreamWriter* writer) const;
+2 -2
View File
@@ -164,13 +164,13 @@ void NodeInputArray::RemoveAt(int index)
RemoveLast();
}
void NodeInputArray::LoadInternal(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections)
void NodeInputArray::LoadInternal(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections, const QAtomicInt* cancelled)
{
if (reader->name() == "subparameters") {
XMLReadLoop(reader, "subparameters") {
if (reader->name() == "input") {
Append();
At(GetSize() - 1)->Load(reader, param_ptrs, input_connections, footage_connections);
At(GetSize() - 1)->Load(reader, param_ptrs, input_connections, footage_connections, cancelled);
}
}
}
+1 -1
View File
@@ -33,7 +33,7 @@ signals:
void SizeChanged(int size);
protected:
virtual void LoadInternal(QXmlStreamReader* reader, QHash<quintptr, NodeOutput *> &param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections) override;
virtual void LoadInternal(QXmlStreamReader* reader, QHash<quintptr, NodeOutput *> &param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections, const QAtomicInt *cancelled) override;
virtual void SaveInternal(QXmlStreamWriter* writer) const override;
+6 -2
View File
@@ -50,9 +50,13 @@ Node::~Node()
}
}
void Node::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput *> &output_ptrs, QList<NodeInput::SerializedConnection>& input_connections, QList<NodeParam::FootageConnection>& footage_connections, const QString& element)
void Node::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput *> &output_ptrs, QList<NodeInput::SerializedConnection>& input_connections, QList<NodeParam::FootageConnection>& footage_connections, const QAtomicInt* cancelled, const QString& element)
{
XMLReadLoop(reader, (element.isEmpty() ? "node" : element)) {
if (cancelled && *cancelled) {
return;
}
if (reader->isStartElement()) {
if (reader->name() == "input" || reader->name() == "output") {
QString param_id;
@@ -77,7 +81,7 @@ void Node::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput *> &output_
continue;
}
param->Load(reader, output_ptrs, input_connections, footage_connections);
param->Load(reader, output_ptrs, input_connections, footage_connections, cancelled);
}
}
}
+1 -1
View File
@@ -67,7 +67,7 @@ public:
/**
* @brief Clear current node variables and replace them with
*/
void Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<NodeInput::SerializedConnection> &input_connections, QList<NodeParam::FootageConnection>& footage_connections, const QString &element = QString());
void Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<NodeInput::SerializedConnection> &input_connections, QList<NodeParam::FootageConnection>& footage_connections, const QAtomicInt *cancelled, const QString &element = QString());
/**
* @brief Save this node into a text/XML format
+5 -1
View File
@@ -42,9 +42,13 @@ QString NodeOutput::name()
return NodeParam::name();
}
void NodeOutput::Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection>&, QList<FootageConnection>&)
void NodeOutput::Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection>&, QList<FootageConnection>&, const QAtomicInt *cancelled)
{
XMLAttributeLoop(reader, attr) {
if (cancelled && *cancelled) {
return;
}
if (attr.name() == "ptr") {
quintptr saved_ptr = attr.value().toULongLong();
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual QString name() override;
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections) override;
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections, const QAtomicInt* cancelled) override;
virtual void Save(QXmlStreamWriter* writer) const override;
+1 -1
View File
@@ -242,7 +242,7 @@ public:
/**
* @brief Load function
*/
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections) = 0;
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections, const QAtomicInt* cancelled) = 0;
/**
* @brief Save function
+10 -2
View File
@@ -44,15 +44,23 @@ QIcon Folder::icon()
return icon::Folder;
}
void Folder::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr> &footage_ptrs, QList<NodeParam::FootageConnection>& footage_connections)
void Folder::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr> &footage_ptrs, QList<NodeParam::FootageConnection>& footage_connections, const QAtomicInt *cancelled)
{
XMLAttributeLoop(reader, attr) {
if (cancelled && *cancelled) {
return;
}
if (attr.name() == "name") {
set_name(attr.value().toString());
}
}
XMLReadLoop(reader, "folder") {
if (cancelled && *cancelled) {
return;
}
if (reader->isStartElement()) {
ItemPtr child;
@@ -67,7 +75,7 @@ void Folder::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr> &footage_
}
add_child(child);
child->Load(reader, footage_ptrs, footage_connections);
child->Load(reader, footage_ptrs, footage_connections, cancelled);
}
}
}
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual QIcon icon() override;
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, StreamPtr> &footage_ptrs, QList<NodeParam::FootageConnection> &footage_connections) override;
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, StreamPtr> &footage_ptrs, QList<NodeParam::FootageConnection> &footage_connections, const QAtomicInt *cancelled) override;
virtual void Save(QXmlStreamWriter* writer) const override;
+10 -2
View File
@@ -37,7 +37,7 @@ Footage::~Footage()
ClearStreams();
}
void Footage::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr>& footage_ptrs, QList<NodeParam::FootageConnection>&)
void Footage::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr>& footage_ptrs, QList<NodeParam::FootageConnection>&, const QAtomicInt* cancelled)
{
QXmlStreamAttributes attributes = reader->attributes();
@@ -49,15 +49,23 @@ void Footage::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr>& footage
}
}
Decoder::ProbeMedia(this);
Decoder::ProbeMedia(this, cancelled);
XMLReadLoop(reader, "footage") {
if (cancelled && *cancelled) {
return;
}
if (reader->isStartElement()) {
if (reader->name() == "stream") {
int stream_index = -1;
quintptr stream_ptr = 0;
XMLAttributeLoop(reader, attr) {
if (cancelled && *cancelled) {
return;
}
if (attr.name() == "index") {
stream_index = attr.value().toInt();
} else if (attr.name() == "ptr") {
+1 -1
View File
@@ -63,7 +63,7 @@ public:
/**
* @brief Load function
*/
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, StreamPtr> &footage_ptrs, QList<NodeParam::FootageConnection> &footage_connections) override;
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, StreamPtr> &footage_ptrs, QList<NodeParam::FootageConnection> &footage_connections, const QAtomicInt *cancelled) override;
/**
* @brief Save function
+14 -2
View File
@@ -42,9 +42,13 @@ Sequence::Sequence()
AddNode(viewer_output_);
}
void Sequence::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr> &, QList<NodeInput::FootageConnection>& footage_connections)
void Sequence::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr> &, QList<NodeInput::FootageConnection>& footage_connections, const QAtomicInt *cancelled)
{
XMLAttributeLoop(reader, attr) {
if (cancelled && *cancelled) {
return;
}
if (attr.name() == "name") {
set_name(attr.value().toString());
@@ -56,12 +60,20 @@ void Sequence::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr> &, QLis
QList<NodeParam::SerializedConnection> desired_connections;
XMLReadLoop(reader, "sequence") {
if (cancelled && *cancelled) {
return;
}
if (reader->isStartElement()) {
if (reader->name() == "video") {
int video_width, video_height;
rational video_timebase;
XMLReadLoop(reader, "video") {
if (cancelled && *cancelled) {
return;
}
if (reader->isStartElement()) {
if (reader->name() == "width") {
reader->readNext();
@@ -125,7 +137,7 @@ void Sequence::Load(QXmlStreamReader *reader, QHash<quintptr, StreamPtr> &, QLis
}
if (node) {
node->Load(reader, output_ptrs, desired_connections, footage_connections, reader->name().toString());
node->Load(reader, output_ptrs, desired_connections, footage_connections, cancelled, reader->name().toString());
AddNode(node);
}
+1 -1
View File
@@ -42,7 +42,7 @@ public:
/**
* @brief Load function
*/
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, StreamPtr> &footage_ptrs, QList<NodeParam::FootageConnection> &footage_connections) override;
virtual void Load(QXmlStreamReader* reader, QHash<quintptr, StreamPtr> &footage_ptrs, QList<NodeParam::FootageConnection> &footage_connections, const QAtomicInt* cancelled) override;
/**
* @brief Save function
+3 -3
View File
@@ -25,7 +25,7 @@
#include "common/xmlreadloop.h"
#include "core.h"
#include "dialog/loadsave/loadsave.h"
#include "dialog/progress/progress.h"
#include "window/mainwindow/mainwindow.h"
Project::Project()
@@ -33,7 +33,7 @@ Project::Project()
root_.set_project(this);
}
void Project::Load(QXmlStreamReader *reader)
void Project::Load(QXmlStreamReader *reader, const QAtomicInt* cancelled)
{
QHash<quintptr, StreamPtr> footage_ptrs;
QList<NodeInput::FootageConnection> footage_connections;
@@ -43,7 +43,7 @@ void Project::Load(QXmlStreamReader *reader)
if (reader->name() == "folder") {
// Assume this folder is our root
root_.Load(reader, footage_ptrs, footage_connections);
root_.Load(reader, footage_ptrs, footage_connections, cancelled);
} else if (reader->name() == "colormanagement") {
+1 -1
View File
@@ -44,7 +44,7 @@ class Project : public QObject
public:
Project();
void Load(QXmlStreamReader* reader);
void Load(QXmlStreamReader* reader, const QAtomicInt* cancelled);
void Save(QXmlStreamWriter* writer) const;