various: added hooks so that various lengthy functions could be cancelled from another thread
This commit is contained in:
+10
-6
@@ -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 ¶ms)
|
||||
void Decoder::Conform(const AudioRenderingParams ¶ms, 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
@@ -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_;
|
||||
|
||||
@@ -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 ¶ms)
|
||||
FramePtr FFmpegDecoder::RetrieveAudio(const rational &timecode, const rational &length, const AudioRenderingParams ¶ms, 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 ¶ms)
|
||||
void FFmpegDecoder::Conform(const AudioRenderingParams ¶ms, 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 ¶ms)
|
||||
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 ¶ms)
|
||||
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 ¶ms)
|
||||
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,11 +899,16 @@ void FFmpegDecoder::UnconditionalVideoIndex(AVPacket* pkt, AVFrame* frame)
|
||||
}
|
||||
}
|
||||
|
||||
video_stream->append_frame_index(VideoStream::kEndTimestamp);
|
||||
// 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());
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -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 ¶ms);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ signals:
|
||||
void SizeChanged(int size);
|
||||
|
||||
protected:
|
||||
virtual void LoadInternal(QXmlStreamReader* reader, QHash<quintptr, NodeOutput *> ¶m_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections) override;
|
||||
virtual void LoadInternal(QXmlStreamReader* reader, QHash<quintptr, NodeOutput *> ¶m_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections, const QAtomicInt *cancelled) override;
|
||||
|
||||
virtual void SaveInternal(QXmlStreamWriter* writer) const override;
|
||||
|
||||
|
||||
+6
-2
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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") {
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user