decoder/renderer: no longer index automatically as part of the retrieve

functions

Indexing is a lengthy process and had a high chance of getting RenderWorkers
stuck doing it rather than being responsive to cache requests. This commit
introduces a system where workers never index media, but instead signal that
media is not ready to their RenderBackends which ensure that the media gets
indexed and re-queues the affected frames when those indexes are ready.
This commit is contained in:
itsmattkc
2020-02-19 11:44:29 +11:00
parent 5e75e9b3b0
commit 03bdf01357
28 changed files with 461 additions and 197 deletions
+47 -24
View File
@@ -38,7 +38,7 @@ NodeValueTable VideoRenderWorker::RenderInternal(const NodeDependency& path, con
hasher.addData(reinterpret_cast<const char*>(&vfmt), sizeof(PixelFormat::Format));
hasher.addData(reinterpret_cast<const char*>(&vmode), sizeof(RenderMode::Mode));
HashNodeRecursively(&hasher, path.node(), path.in(), &IsCancelled());
HashNodeRecursively(&hasher, path.node(), path.in());
hash = hasher.result();
}
@@ -87,12 +87,12 @@ NodeValueTable VideoRenderWorker::RenderInternal(const NodeDependency& path, con
return value;
}
FramePtr VideoRenderWorker::RetrieveFromDecoder(DecoderPtr decoder, const TimeRange &range, const QAtomicInt* cancelled)
FramePtr VideoRenderWorker::RetrieveFromDecoder(DecoderPtr decoder, const TimeRange &range)
{
return decoder->RetrieveVideo(range.in(), cancelled);
return decoder->RetrieveVideo(range.in());
}
void VideoRenderWorker::HashNodeRecursively(QCryptographicHash *hash, const Node* n, const rational& time, const QAtomicInt* cancelled)
void VideoRenderWorker::HashNodeRecursively(QCryptographicHash *hash, const Node* n, const rational& time)
{
// Resolve BlockList
if (n->IsTrack()) {
@@ -140,7 +140,7 @@ void VideoRenderWorker::HashNodeRecursively(QCryptographicHash *hash, const Node
if (input->IsConnected()) {
// Traverse down this edge
HashNodeRecursively(hash, input->get_connected_node(), input_time, cancelled);
HashNodeRecursively(hash, input->get_connected_node(), input_time);
} else {
// Grab the value at this time
QVariant value = input->get_value_at_time(input_time);
@@ -150,32 +150,48 @@ void VideoRenderWorker::HashNodeRecursively(QCryptographicHash *hash, const Node
// We have one exception for FOOTAGE types, since we resolve the footage into a frame in the renderer
if (input->data_type() == NodeParam::kFootage) {
StreamPtr stream = ResolveStreamFromInput(input);
DecoderPtr decoder = ResolveDecoderFromInput(stream);
if (decoder != nullptr) {
// Add footage details to hash
if (stream) {
DecoderPtr decoder = ResolveDecoderFromInput(stream);
// Footage filename
hash->addData(stream->footage()->filename().toUtf8());
if (decoder) {
// Footage last modified date
hash->addData(stream->footage()->timestamp().toString().toUtf8());
// Add footage details to hash
// Footage stream
hash->addData(QString::number(stream->index()).toUtf8());
// Footage filename
hash->addData(stream->footage()->filename().toUtf8());
if (stream->type() == Stream::kImage || stream->type() == Stream::kVideo) {
ImageStreamPtr video_stream = std::static_pointer_cast<ImageStream>(stream);
// Footage last modified date
hash->addData(stream->footage()->timestamp().toString().toUtf8());
// Footage stream
hash->addData(QString::number(stream->index()).toUtf8());
if (stream->type() == Stream::kImage || stream->type() == Stream::kVideo) {
ImageStreamPtr image_stream = std::static_pointer_cast<ImageStream>(stream);
// Current color config and space
hash->addData(image_stream->footage()->project()->ocio_config().toUtf8());
hash->addData(image_stream->colorspace().toUtf8());
// Alpha associated setting
hash->addData(QString::number(image_stream->premultiplied_alpha()).toUtf8());
}
// Footage timestamp
hash->addData(QString::number(decoder->GetTimestampFromTime(input_time, cancelled)).toUtf8());
if (stream->type() == Stream::kVideo) {
Decoder::RetrieveState state = decoder->GetRetrieveState(input_time);
// Current color config and space
hash->addData(video_stream->footage()->project()->ocio_config().toUtf8());
hash->addData(video_stream->colorspace().toUtf8());
if (state == Decoder::kReady) {
VideoStreamPtr video_stream = std::static_pointer_cast<VideoStream>(stream);
// Alpha associated setting
hash->addData(QString::number(video_stream->premultiplied_alpha()).toUtf8());
int64_t timestamp_here = video_stream->get_closest_timestamp_in_frame_index(input_time);
hash->addData(QString::number(timestamp_here).toUtf8());
} else {
ReportUnavailableFootage(stream, state, input_time);
}
}
}
}
}
@@ -258,13 +274,20 @@ NodeValueTable VideoRenderWorker::RenderBlock(const TrackOutput *track, const Ti
NodeValueTable table;
if (active_block) {
table = ProcessNode(NodeDependency(active_block,
range));
table = ProcessNode(NodeDependency(active_block, range));
}
return table;
}
void VideoRenderWorker::ReportUnavailableFootage(StreamPtr stream, Decoder::RetrieveState state, const rational &stream_time)
{
emit FootageUnavailable(stream,
state,
TimeRange(CurrentPath().in(), CurrentPath().in() + video_params().time_base()),
stream_time);
}
ColorProcessorCache *VideoRenderWorker::color_cache()
{
return &color_cache_;