fix: black preview when footage connects directly to a clip
ClipBlock::kBufferIn is declared as NodeValue::kNone with no value hint, so when a footage node is connected straight to a clip's buffer input (no effect node in between), the traverser has no type to look up in the footage's value table and falls back to its last entry. A footage pushes its video texture first and its audio samples last, so a video clip ended up fed with audio samples, produced no texture and the preview went silently black. With any node in between, the table only carries the passthrough texture, which is why the bug only showed on direct connections. Make Node::GetValueHintForInput virtual and override it in ClipBlock to prefer the value type matching the clip's track (kTexture on video tracks, kSamples on audio tracks). Regression tests cover the exact application render path (PreviewAutoCacher -> RenderManager -> RenderWorkerPool -> oak-render-worker) for both the direct and indirect cases, the hint following the track type, and viewer display widgets. The direct-case test reproduces the black frame without the fix and passes with it. Full suite: 584 passed.
This commit is contained in:
@@ -141,6 +141,30 @@ rational ClipBlock::media_in() const
|
||||
return GetStandardValue(kMediaInInput).value<rational>();
|
||||
}
|
||||
|
||||
Node::ValueHint ClipBlock::GetValueHintForInput(const QString &input,
|
||||
int element) const
|
||||
{
|
||||
if (input == kBufferIn) {
|
||||
// The buffer input takes whatever the connected node provides, so it
|
||||
// is declared as kNone and carries no stored hint. When the connected
|
||||
// node pushes more than one value type (a footage pushes both a
|
||||
// kTexture job and a kSamples job), a typeless lookup falls back to
|
||||
// the last value in the table, which may feed audio samples into a
|
||||
// video clip and produce a black frame. Prefer the value type that
|
||||
// matches this clip's track.
|
||||
switch (GetTrackType()) {
|
||||
case Track::kVideo:
|
||||
return ValueHint(QVector<NodeValue::Type>{ NodeValue::kTexture });
|
||||
case Track::kAudio:
|
||||
return ValueHint(QVector<NodeValue::Type>{ NodeValue::kSamples });
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return super::GetValueHintForInput(input, element);
|
||||
}
|
||||
|
||||
void ClipBlock::set_media_in(const rational &media_in)
|
||||
{
|
||||
SetStandardValue(kMediaInInput, QVariant::fromValue(media_in));
|
||||
|
||||
@@ -59,6 +59,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual Node::ValueHint
|
||||
GetValueHintForInput(const QString &input, int element = -1) const override;
|
||||
|
||||
rational media_in() const;
|
||||
void set_media_in(const rational &media_in);
|
||||
|
||||
|
||||
+2
-1
@@ -802,7 +802,8 @@ public:
|
||||
return value_hints_;
|
||||
}
|
||||
|
||||
ValueHint GetValueHintForInput(const QString &input, int element = -1) const
|
||||
virtual ValueHint GetValueHintForInput(const QString &input,
|
||||
int element = -1) const
|
||||
{
|
||||
return value_hints_.value({ input, element });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user