Tone-map HDR before stabilization and prioritize stable conservative framing

This commit is contained in:
Mikei386
2026-09-13 12:24:13 +02:00
parent 031dc50b99
commit a4919bedd0
8 changed files with 113 additions and 61 deletions
+53
View File
@@ -35,6 +35,31 @@ struct RenderIntegration {
throw TestFailure.failed("Real project validation failed: \(validator.state)")
}
print("PASS real project load: \(project.clips.count) clips")
if ProcessInfo.processInfo.environment["GROWTHLAPSE_TEST_QUALITY"] == "1" {
let original = try Data(contentsOf: URL(fileURLWithPath: path))
var subset = project
let prefixes = ["035", "062", "184"]
subset.clips = project.clips.filter { c in prefixes.contains { c.displayName.hasPrefix($0) } }
try require(subset.clips.count == 3, "Expected three visual regression clips")
validator.project = subset
var settings = SettingsStore.load()
let folder = FileManager.default.temporaryDirectory.appendingPathComponent("GrowthLapse-quality-\(UUID().uuidString)")
try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
settings.outputFile = folder.appendingPathComponent("Vergleich-neu.mp4")
settings.keepIntermediateClips = true
settings.keepRenderCacheForReview = true
validator.rerenderProject(settings: settings)
let deadline = Date().addingTimeInterval(300)
while validator.state.isRunning && Date() < deadline { try await Task.sleep(nanoseconds: 100_000_000) }
guard case .finished(let output) = validator.state else {
validator.cancel()
throw TestFailure.failed("Quality render: \(validator.state)\n\(validator.logs.suffix(25).joined(separator: "\n"))")
}
let after = try Data(contentsOf: URL(fileURLWithPath: path))
try require(original == after, "Quality check changed user's project")
print("PASS real full-resolution quality render: \(output.path)")
return
}
if ProcessInfo.processInfo.environment["GROWTHLAPSE_TEST_REAL_DRAFT"] == "1" {
let original = try Data(contentsOf: URL(fileURLWithPath: path))
var subset = project
@@ -380,6 +405,34 @@ struct RenderIntegration {
try require(!manager.fileExists(atPath: goodProject.cacheDirectoryPath), "Owned cache was not deleted")
try require(manager.fileExists(atPath: goodProject.outputFilePath), "Confirm deleted output")
print("PASS cancelled rerender preserves old cache and confirm only deletes owned cache")
// HDR must become SDR before the first stabilization intermediate.
let hdrInput = root.appendingPathComponent("hdr", isDirectory: true)
try manager.createDirectory(at: hdrInput, withIntermediateDirectories: true)
let hdrSource = hdrInput.appendingPathComponent("hdr.mkv")
let hdrFixture = try await service.run(executable: tools.ffmpeg, arguments: [
"-v", "error", "-y", "-f", "lavfi", "-i", "color=c=gray:s=320x240:r=15:d=1",
"-pix_fmt", "yuv420p10le", "-c:v", "ffv1", "-color_primaries", "bt2020",
"-color_trc", "arib-std-b67", "-colorspace", "bt2020nc", hdrSource.path])
try require(hdrFixture.exitCode == 0, "HDR fixture generation failed")
var hdrSettings = RenderSettings()
hdrSettings.inputFolder = hdrInput
hdrSettings.outputFile = root.appendingPathComponent("HDR.mp4")
hdrSettings.outputFormat = .keepOriginal
hdrSettings.videoEncoder = .x264
hdrSettings.segmentLength = 1
hdrSettings.targetClipLength = 1
hdrSettings.transitionLength = 0
hdrSettings.stabilizationEnabled = true
hdrSettings.keepIntermediateClips = true
let hdrProcessor = VideoProcessor()
hdrProcessor.start(settings: hdrSettings)
try await wait(hdrProcessor)
let intermediate = hdrProcessor.project!.cacheDirectoryURL.appendingPathComponent("segment_0001.mp4")
let hdrProbe = try await probe(intermediate, tools: service, ffprobe: tools.ffprobe)
let hdrStreams = hdrProbe["streams"] as! [[String: Any]]
try require(hdrStreams[0]["color_transfer"] as? String == "bt709"
&& hdrStreams[0]["color_primaries"] as? String == "bt709", "HDR persisted into 8-bit stabilization intermediate")
print("PASS 10-bit HLG source converted to SDR before stabilization encoding")
print("All integration checks passed.")
}
}