Add extension-frame refine and lossless anchor options.
Prefer clip anchor PNGs for handoffs, optionally run Bilateral+Flux cleanup before I2V, and save decoded last-frame anchors so sequential extensions accumulate less compression damage. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -56,6 +56,9 @@ export interface PendingJob {
|
||||
queueAutoRun?: boolean
|
||||
queueBudget?: number
|
||||
stopAfterCurrent?: boolean
|
||||
refineExtensionFrame?: boolean
|
||||
saveLosslessAnchor?: boolean
|
||||
refinementDenoise?: number
|
||||
loraName?: string
|
||||
loraStack?: import('~/utils/loras').LoraStackItem[]
|
||||
shotLoras?: string[]
|
||||
@@ -155,6 +158,9 @@ export function pendingFromJob(job: Job, overrides: Partial<PendingJob> = {}): P
|
||||
queueAutoRun: library.queueAutoRun,
|
||||
queueBudget: library.queueBudget,
|
||||
stopAfterCurrent: library.stopAfterCurrent,
|
||||
refineExtensionFrame: library.refineExtensionFrame,
|
||||
saveLosslessAnchor: library.saveLosslessAnchor,
|
||||
refinementDenoise: library.refinementDenoise,
|
||||
...overrides
|
||||
}
|
||||
}
|
||||
@@ -203,6 +209,9 @@ export function libraryFromPending(pending: PendingJob): NonNullable<Job['librar
|
||||
queueAutoRun: pending.queueAutoRun,
|
||||
queueBudget: pending.queueBudget,
|
||||
stopAfterCurrent: pending.stopAfterCurrent,
|
||||
refineExtensionFrame: pending.refineExtensionFrame,
|
||||
saveLosslessAnchor: pending.saveLosslessAnchor,
|
||||
refinementDenoise: pending.refinementDenoise,
|
||||
globalLocks: pending.globalLocks,
|
||||
permanenceRefs: pending.permanenceRefs,
|
||||
shotPermanenceRefs: pending.shotPermanenceRefs,
|
||||
@@ -342,6 +351,32 @@ export async function completePendingIfReady(pending: PendingJob) {
|
||||
loraStack: pending.loraStack,
|
||||
segmentFirstFrame
|
||||
})
|
||||
if (pending.saveLosslessAnchor === true) {
|
||||
try {
|
||||
const { persistClipAnchorFrame, extractAnchorImageFromHistory, downloadAnchorImage } = await import('~/server/utils/extensionFrame')
|
||||
let saved = false
|
||||
const anchorImage = extractAnchorImageFromHistory(history, pending.promptId)
|
||||
if (anchorImage) {
|
||||
const png = await downloadAnchorImage(anchorImage)
|
||||
if (png.length >= 64) {
|
||||
await persistClipAnchorFrame({
|
||||
ownerKey: pending.ownerKey,
|
||||
clipId: clip.id,
|
||||
fromBuffer: png
|
||||
})
|
||||
saved = true
|
||||
}
|
||||
}
|
||||
if (!saved) {
|
||||
await persistClipAnchorFrame({
|
||||
ownerKey: pending.ownerKey,
|
||||
clipId: clip.id
|
||||
})
|
||||
}
|
||||
} catch {
|
||||
/* optional */
|
||||
}
|
||||
}
|
||||
await purgeComfyArtifacts({
|
||||
video,
|
||||
imageName: pending.imageName,
|
||||
|
||||
Reference in New Issue
Block a user