Stop resampling the extend start frame every hop
upload() ran fitStill (ffmpeg scale+pad) on every image except hero, including the start/handoff still. Four chained extends resampled the anchor frame four times and destroyed identity even with the hero reference and lock text intact. - upload(): only fit when the still's aspect truly differs from the job canvas (needsFit); never fit hero or start regardless. - Track handoffSource (anchor|extract) and whether the start frame was fitted; surface both in job metadata and Details. - extendSelected(): re-binding an already-selected clip on task switch must not stomp the user's overridden locks/settings back to the clip's saved values (regression introduced by the last hotfix push). - Add tests/studio2-extend-fit.test.mjs: two extends at identical width/height reach Comfy with the anchor PNG byte-identical, no ffmpeg fit. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { mkdtempSync, writeFileSync, readFileSync, rmSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { runFfmpeg } from '../ffmpeg'
|
||||
import { imageDimensions } from '../resolution'
|
||||
export async function fitStill(data: Buffer, width: number, height: number) {
|
||||
const dir=mkdtempSync(join(tmpdir(),'studio2-fit-'))
|
||||
try {
|
||||
@@ -11,3 +12,12 @@ export async function fitStill(data: Buffer, width: number, height: number) {
|
||||
return readFileSync(output)
|
||||
} finally { rmSync(dir,{recursive:true,force:true}) }
|
||||
}
|
||||
/** Only scale/pad when the still's aspect truly differs from the job canvas.
|
||||
* A matching frame (typical extend handoff) must reach Comfy byte-identical. */
|
||||
export function needsFit(data: Buffer, width: number, height: number) {
|
||||
const size = imageDimensions(data)
|
||||
if (!size?.width || !size?.height) return true
|
||||
if (size.width === width && size.height === height) return false
|
||||
const target = width / height, actual = size.width / size.height
|
||||
return Math.abs(target - actual) > 0.01
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user