Skip to content

Commit 1d0d5bd

Browse files
Fix false telecine detection on VHS tapes, bump version to 0.7.1
Scan type detection was misclassifying interlaced PAL VHS content as hard telecine because any single repeated field (repeatedFields > 0) triggered telecine. VHS tapes produce stray repeated fields from tracking instability, especially at the start. Now requires >= 15% repeated fields ratio, matching real 3:2 pulldown (~40%) while filtering out VHS noise. Also skips the first 2s of longer videos to avoid unstable VHS leader sections. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4c8d157 commit 1d0d5bd

5 files changed

Lines changed: 21 additions & 10 deletions

File tree

app/lib/services/field_order_detector.dart

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class FieldOrderDetector {
8585

8686
// Run idet and repeat_pict analysis in parallel
8787
final results = await Future.wait([
88-
_runIdet(videoPath),
88+
_runIdet(videoPath, duration: duration),
8989
_detectSoftTelecine(videoPath),
9090
]);
9191
final idet = results[0] as _IdetResult?;
@@ -132,14 +132,21 @@ class FieldOrderDetector {
132132
/// - Interlaced vs progressive content
133133
/// - Field order (TFF/BFF)
134134
/// - Repeated fields (indicates hard telecine)
135-
Future<_IdetResult?> _runIdet(String videoPath) async {
135+
///
136+
/// When [duration] is known and > 4s, skips the first 2s to avoid
137+
/// VHS leader/tracking instability.
138+
Future<_IdetResult?> _runIdet(String videoPath, {double? duration}) async {
136139
final ffmpeg = ToolLocator.instance.ffmpegPath;
137140
if (ffmpeg == null) return null;
138141

142+
// Skip first 2s for longer videos to avoid VHS leader/tracking instability
143+
final skipSeconds = (duration != null && duration > 4.0) ? 2 : 0;
144+
139145
try {
140146
final result = await Process.run(
141147
ffmpeg,
142148
[
149+
if (skipSeconds > 0) ...['-ss', '$skipSeconds'],
143150
'-i', videoPath,
144151
'-vf', 'idet',
145152
'-frames:v', '200',
@@ -251,8 +258,12 @@ class FieldOrderDetector {
251258
}
252259
}
253260

254-
// Hard telecine: interlaced frames with significant repeated fields
255-
if (interlacedRatio > 0.5 && repeatedFields > 0) {
261+
// Hard telecine: interlaced frames with significant repeated fields.
262+
// True 3:2 pulldown shows ~40% repeated fields, 2:2 shows ~50%.
263+
// Require at least 15% to avoid false positives from VHS tracking
264+
// artifacts or other analog noise (especially at tape start).
265+
final repeatedRatio = total > 0 ? repeatedFields / total : 0.0;
266+
if (interlacedRatio > 0.5 && repeatedRatio > 0.15) {
256267
return ScanType.telecine;
257268
}
258269

app/macos/Runner/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
<key>CFBundlePackageType</key>
1818
<string>APPL</string>
1919
<key>CFBundleShortVersionString</key>
20-
<string>0.7.0</string>
20+
<string>0.7.1</string>
2121
<key>CFBundleVersion</key>
22-
<string>0.7.0</string>
22+
<string>0.7.1</string>
2323
<key>LSMinimumSystemVersion</key>
2424
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
2525
<key>NSHumanReadableCopyright</key>

app/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: vapourbox
22
description: "Video restoration and cleanup powered by VapourSynth"
33
publish_to: 'none'
4-
version: 0.7.0+12
4+
version: 0.7.1+13
55

66
environment:
77
sdk: ^3.6.2

app/windows/runner/Runner.rc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ IDI_APP_ICON ICON "resources\\app_icon.ico"
7373
#endif
7474

7575
VS_VERSION_INFO VERSIONINFO
76-
FILEVERSION 0,7,0,0
77-
PRODUCTVERSION 0,7,0,0
76+
FILEVERSION 0,7,1,0
77+
PRODUCTVERSION 0,7,1,0
7878
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
7979
#ifdef _DEBUG
8080
FILEFLAGS VS_FF_DEBUG

worker/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "vapourbox-worker"
3-
version = "0.7.0"
3+
version = "0.7.1"
44
edition = "2021"
55
description = "Video restoration worker using VapourSynth"
66
authors = ["Stuart Cameron"]

0 commit comments

Comments
 (0)