okay maybe not
This commit is contained in:
@@ -197,30 +197,59 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const TrackOutput *track, con
|
||||
|
||||
QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational &input_time)
|
||||
{
|
||||
Renderer::TexturePtr value = nullptr;
|
||||
|
||||
// Check the still frame cache. On large frames such as high resolution still images, uploading
|
||||
// and color managing them for every frame is a waste of time, so we implement a small cache here
|
||||
// to optimize such a situation
|
||||
VideoStreamPtr video_stream = std::static_pointer_cast<VideoStream>(stream);
|
||||
rational time_match = (video_stream->video_type() == VideoStream::kVideoTypeStill) ? 0 : input_time;
|
||||
QString colorspace_match = video_stream->get_colorspace_match_string();
|
||||
|
||||
QVariant value;
|
||||
bool found_cache = false;
|
||||
|
||||
const VideoParams& video_params = Node::ValueToPtr<ViewerOutput>(ticket_->property("viewer"))->video_params();
|
||||
StillImageCache::Entry want_entry = {nullptr,
|
||||
stream,
|
||||
video_stream->get_colorspace_match_string(),
|
||||
video_stream->premultiplied_alpha(),
|
||||
video_params.divider(),
|
||||
(video_stream->video_type() == VideoStream::kVideoTypeStill) ? 0 : input_time};
|
||||
|
||||
if (still_image_cache_.contains(stream.get())) {
|
||||
const CachedStill& cs = still_image_cache_[stream.get()];
|
||||
still_image_cache_->mutex()->lock();
|
||||
|
||||
if (cs.colorspace == colorspace_match
|
||||
&& cs.alpha_is_associated == video_stream->premultiplied_alpha()
|
||||
&& cs.divider == video_params.divider()
|
||||
&& cs.time == time_match) {
|
||||
value = cs.texture;
|
||||
found_cache = true;
|
||||
} else {
|
||||
still_image_cache_.remove(stream.get());
|
||||
foreach (const StillImageCache::Entry& 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_cache) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value) {
|
||||
// Found the texture, we can release the cache now
|
||||
still_image_cache_->mutex()->unlock();
|
||||
} 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);
|
||||
|
||||
still_image_cache_->mutex()->unlock();
|
||||
|
||||
DecoderPtr decoder = ResolveDecoderFromInput(stream);
|
||||
|
||||
@@ -230,22 +259,26 @@ QVariant RenderProcessor::ProcessVideoFootage(StreamPtr stream, const rational &
|
||||
|
||||
if (frame) {
|
||||
// Return a texture from the derived class
|
||||
Renderer::TexturePtr unmanaged_texture = render_ctx_->CreateTexture(frame->video_params(), frame->data(), frame->linesize_pixels());
|
||||
|
||||
Renderer::TexturePtr managed_texture = render_ctx_->TransformColor(unmanaged_texture, )
|
||||
|
||||
value = FootageFrameToTexture(stream, frame);
|
||||
|
||||
if (!value.isNull()) {
|
||||
// Put this into the image cache instead
|
||||
still_image_cache_.insert(stream.get(), {value,
|
||||
colorspace_match,
|
||||
video_stream->premultiplied_alpha(),
|
||||
video_params .divider(),
|
||||
time_match});
|
||||
}
|
||||
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);
|
||||
|
||||
still_image_cache_->mutex()->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return value;
|
||||
return QVariant::fromValue(value);
|
||||
}
|
||||
|
||||
QVariant RenderProcessor::ProcessAudioFootage(StreamPtr stream, const TimeRange &input_time)
|
||||
@@ -369,7 +402,9 @@ QVariant RenderProcessor::ProcessFrameGeneration(const Node *node, const Generat
|
||||
|
||||
node->GenerateFrame(frame, job);
|
||||
|
||||
return CachedFrameToTexture(frame);
|
||||
Renderer::TexturePtr texture = render_ctx_->CreateTexture(frame->video_params(), frame->data(), frame->linesize_pixels());
|
||||
|
||||
return QVariant::fromValue(texture);
|
||||
}
|
||||
|
||||
QVariant RenderProcessor::GetCachedFrame(const Node *node, const rational &time)
|
||||
@@ -393,7 +428,8 @@ QVariant RenderProcessor::GetCachedFrame(const Node *node, const rational &time)
|
||||
f->video_params().interlacing(),
|
||||
video_params.divider()));
|
||||
|
||||
return CachedFrameToTexture(f);
|
||||
Renderer::TexturePtr texture = render_ctx_->CreateTexture(f->video_params(), f->data(), f->linesize_pixels());
|
||||
return QVariant::fromValue(texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user