renderer: fixed bug that caused threads to hang indefinitely
This commit is contained in:
@@ -265,39 +265,32 @@ QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational &
|
||||
|
||||
ColorManager* color_manager = Node::ValueToPtr<ColorManager>(ticket_->property("colormanager"));
|
||||
|
||||
StillImageCache::Entry want_entry = {nullptr,
|
||||
stream,
|
||||
ColorProcessor::GenerateID(color_manager, video_stream->colorspace(), color_manager->GetReferenceColorSpace()),
|
||||
video_stream->premultiplied_alpha(),
|
||||
video_params.divider(),
|
||||
(video_stream->video_type() == VideoStream::kVideoTypeStill) ? 0 : input_time};
|
||||
StillImageCache::EntryPtr want_entry = std::make_shared<StillImageCache::Entry>(
|
||||
nullptr,
|
||||
stream,
|
||||
ColorProcessor::GenerateID(color_manager, video_stream->colorspace(), color_manager->GetReferenceColorSpace()),
|
||||
video_stream->premultiplied_alpha(),
|
||||
video_params.divider(),
|
||||
(video_stream->video_type() == VideoStream::kVideoTypeStill) ? 0 : input_time,
|
||||
true);
|
||||
|
||||
bool found_existing = false;
|
||||
|
||||
still_image_cache_->mutex()->lock();
|
||||
|
||||
foreach (const StillImageCache::Entry& e, still_image_cache_->entries()) {
|
||||
foreach (StillImageCache::EntryPtr e, still_image_cache_->entries()) {
|
||||
if (StillImageCache::CompareEntryMetadata(want_entry, e)) {
|
||||
// Found an exact match of the texture we want in the cache, use it instead of reading it
|
||||
// ourselves
|
||||
value = e.texture;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Found an exact match of the texture we want in the cache. See if it's working or if it's
|
||||
// ready.
|
||||
want_entry = e;
|
||||
found_existing = true;
|
||||
|
||||
if (!value) {
|
||||
// Failed to find the texture, let's see if it's being generated by another processor
|
||||
foreach (const StillImageCache::Entry& e, still_image_cache_->pending()) {
|
||||
if (StillImageCache::CompareEntryMetadata(want_entry, e)) {
|
||||
// An exact match of this texture is pending, let's wait for it
|
||||
while (!value) {
|
||||
// FIXME: Hacky way of waiting for other threads
|
||||
still_image_cache_->mutex()->unlock();
|
||||
QThread::msleep(1);
|
||||
still_image_cache_->mutex()->lock();
|
||||
|
||||
value = e.texture;
|
||||
}
|
||||
break;
|
||||
while (want_entry->working) {
|
||||
still_image_cache_->wait_cond()->wait(still_image_cache_->mutex());
|
||||
}
|
||||
|
||||
value = want_entry->texture;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,8 +300,11 @@ QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational &
|
||||
} else {
|
||||
// Wasn't in still image cache, so we'll have to retrieve it from the decoder
|
||||
|
||||
// Let other processors know we're getting this texture
|
||||
still_image_cache_->PushPending(want_entry);
|
||||
// Let other processors know we're getting this texture (want_entry's `working` field is
|
||||
// already set to true in the initializer above)
|
||||
if (!found_existing) {
|
||||
still_image_cache_->PushEntry(want_entry);
|
||||
}
|
||||
|
||||
still_image_cache_->mutex()->unlock();
|
||||
|
||||
@@ -330,7 +326,7 @@ QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational &
|
||||
managed_params.set_format(video_params.format());
|
||||
value = render_ctx_->CreateTexture(managed_params);
|
||||
|
||||
qDebug() << "FIXME: Accessing video_stream->colorspace() and video_stream->premultiplied_alpha() may cause race conditions";
|
||||
//qDebug() << "FIXME: Accessing video_stream->colorspace() and video_stream->premultiplied_alpha() may cause race conditions";
|
||||
|
||||
ColorProcessorPtr processor = ColorProcessor::Create(color_manager,
|
||||
video_stream->colorspace(),
|
||||
@@ -342,11 +338,11 @@ QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational &
|
||||
|
||||
still_image_cache_->mutex()->lock();
|
||||
|
||||
still_image_cache_->RemovePending(want_entry);
|
||||
|
||||
// Put this into the image cache instead
|
||||
want_entry.texture = value;
|
||||
still_image_cache_->PushEntry(want_entry);
|
||||
want_entry->texture = value;
|
||||
want_entry->working = false;
|
||||
|
||||
still_image_cache_->wait_cond()->wakeAll();
|
||||
|
||||
still_image_cache_->mutex()->unlock();
|
||||
}
|
||||
@@ -481,8 +477,6 @@ QVariant RenderProcessor::GetCachedFrame(const Node *node, const rational &time)
|
||||
|
||||
FramePtr f = FrameHashCache::LoadCacheFrame(ticket_->property("cache").toString(), hash);
|
||||
|
||||
qDebug() << ticket_->property("cache").toString() << hash.toHex();
|
||||
|
||||
if (f) {
|
||||
// The cached frame won't load with the correct divider by default, so we enforce it here
|
||||
VideoParams p = f->video_params();
|
||||
@@ -497,8 +491,6 @@ QVariant RenderProcessor::GetCachedFrame(const Node *node, const rational &time)
|
||||
|
||||
TexturePtr texture = render_ctx_->CreateTexture(f->video_params(), f->data(), f->linesize_pixels());
|
||||
return QVariant::fromValue(texture);
|
||||
} else {
|
||||
qDebug() << "Not using cached frame because frame is null";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user