exporter: fixed segfault when cancelling introduced by multithreaded color space conversion

This commit is contained in:
itsmattkc
2020-05-01 00:36:37 +10:00
parent f371aff448
commit afc9cff301
5 changed files with 45 additions and 34 deletions
+38 -27
View File
@@ -224,13 +224,39 @@ QMatrix4x4 Exporter::GenerateMatrix(ExportParams::VideoScalingMethod method, int
return preview_matrix;
}
void Exporter::FrameRendered(const rational &time, FramePtr frame)
FramePtr FrameColorConvert(ColorProcessorPtr processor, FramePtr frame)
{
qDebug() << "Converting" << frame->timestamp();
// OCIO conversion requires a frame in 32F format
if (frame->format() != PixelFormat::PIX_FMT_RGBA32F) {
frame = PixelFormat::ConvertPixelFormat(frame, PixelFormat::PIX_FMT_RGBA32F);
}
// Color conversion must be done with unassociated alpha, and the pipeline is always associated
ColorManager::DisassociateAlpha(frame);
// Convert color space
processor->ConvertFrame(frame);
// Re-associate alpha
ColorManager::ReassociateAlpha(frame);
return frame;
}
void Exporter::FrameRendered(FramePtr frame)
{
// Start color space conversion in another thread
QtConcurrent::run(this,
&Exporter::FrameColorConvert,
time,
frame);
QFutureWatcher<FramePtr>* watcher = new QFutureWatcher<FramePtr>();
connect(watcher, &QFutureWatcher<FramePtr>::finished, this, &Exporter::FrameColorFinished);
QFuture<FramePtr> future = QtConcurrent::run(FrameColorConvert,
color_processor_,
frame);
watcher->setFuture(future);
}
void Exporter::AudioRendered()
@@ -328,36 +354,21 @@ void Exporter::DebugTimerMessage()
qDebug() << "Still waiting for" << waiting_for_frame_.toDouble();
}
void Exporter::FrameColorConvert(const rational &time, FramePtr frame)
void Exporter::FrameColorFinished()
{
// OCIO conversion requires a frame in 32F format
if (frame->format() != PixelFormat::PIX_FMT_RGBA32F) {
frame = PixelFormat::ConvertPixelFormat(frame, PixelFormat::PIX_FMT_RGBA32F);
if (!video_backend_ && !audio_backend_) {
return;
}
// Color conversion must be done with unassociated alpha, and the pipeline is always associated
ColorManager::DisassociateAlpha(frame);
QFutureWatcher<FramePtr>* watcher = static_cast< QFutureWatcher<FramePtr>* >(sender());
FramePtr frame = watcher->result();
watcher->deleteLater();
// Convert color space
color_processor_->ConvertFrame(frame);
// Re-associate alpha
ColorManager::ReassociateAlpha(frame);
QMetaObject::invokeMethod(this,
"FrameColorFinished",
Qt::QueuedConnection,
OLIVE_NS_ARG(rational, time),
OLIVE_NS_ARG(FramePtr, frame));
}
void Exporter::FrameColorFinished(const rational &time, FramePtr frame)
{
debug_timer_.stop();
const QMap<rational, QByteArray>& time_hash_map = video_backend_->frame_cache()->time_hash_map();
QByteArray this_hash = time_hash_map.value(time);
QByteArray this_hash = time_hash_map.value(frame->timestamp());
qDebug() << "Received" << this_hash.toHex();
+2 -4
View File
@@ -101,7 +101,7 @@ private:
QTimer debug_timer_;
private slots:
void FrameRendered(const rational &time, FramePtr frame);
void FrameRendered(FramePtr frame);
void AudioRendered();
@@ -117,9 +117,7 @@ private slots:
void DebugTimerMessage();
void FrameColorConvert(const rational &time, FramePtr frame);
void FrameColorFinished(const OLIVE_NAMESPACE::rational &time, OLIVE_NAMESPACE::FramePtr frame);
void FrameColorFinished();
};
+1 -1
View File
@@ -110,7 +110,7 @@ signals:
void RangeInvalidated(const TimeRange& range);
void GeneratedFrame(const rational &time, FramePtr frame);
void GeneratedFrame(FramePtr frame);
private:
bool TimeIsQueued(const TimeRange &time) const;
+3 -1
View File
@@ -269,7 +269,9 @@ void VideoRenderWorker::Download(const rational& time, QVariant texture, QString
TextureToBuffer(texture, frame->width(), frame->height(), frame_gen_mat_, frame->data(), frame->linesize_pixels());
}
emit GeneratedFrame(time, frame);
frame->set_timestamp(time);
emit GeneratedFrame(frame);
}
}
+1 -1
View File
@@ -79,7 +79,7 @@ signals:
void HashAlreadyExists(NodeDependency path, qint64 job_time, QByteArray hash);
void GeneratedFrame(const rational &time, FramePtr frame);
void GeneratedFrame(FramePtr frame);
void Aborted();