Skip to content

Commit e09b1fe

Browse files
Remove FFMS2 and BestSource dependencies entirely
Both source filter plugins are no longer used — the pipeline now uses FFmpeg pipe source exclusively. Integration tests updated to use BlankClip instead of external source filters, all 12 pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e68f7e2 commit e09b1fe

7 files changed

Lines changed: 15 additions & 113 deletions

File tree

CLAUDE.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,6 @@ The worker sets these via `DependencyLocator`:
842842
### Required Plugins (Windows)
843843

844844
All plugins go in `deps/windows-x64/vapoursynth/vs-plugins/`:
845-
- `ffms2.dll` - Source filter for preview (from [FFMS/ffms2](https://github.com/FFMS/ffms2))
846845
- `libmvtools.dll` - Motion estimation
847846
- `EEDI3m.dll` - Edge-directed interpolation
848847
- `libvs_znedi3.dll` + `nnedi3_weights.bin` - Neural network interpolation
@@ -975,7 +974,6 @@ This runs `xattr -cr` to recursively remove the `com.apple.quarantine` extended
975974
### Required Plugins (macOS)
976975

977976
All plugins are native arm64/x64 builds in `deps/macos-{arch}/vapoursynth/plugins/`:
978-
- `libffms2.dylib` - Source filter for preview (from [FFMS/ffms2](https://github.com/FFMS/ffms2))
979977
- `libmvtools.dylib` - Motion estimation
980978
- `libeedi3m.dylib` - Edge-directed interpolation
981979
- `libznedi3.dylib` + `nnedi3_weights.bin` - Neural network interpolation

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,4 @@ Stuart Cameron - [stuart-cameron.com](https://stuart-cameron.com)
125125

126126
macOS ARM64 plugins sourced from:
127127
- **[yuygfgg/Macos_vapoursynth_plugins](https://github.com/yuygfgg/Macos_vapoursynth_plugins)** — pre-built ARM64 VapourSynth plugins for macOS
128-
- **[FFMS/ffms2](https://github.com/FFMS/ffms2)**FFMS2 source filter (used for preview)
128+
- **[Stefan-Olt/vs-plugin-build](https://github.com/Stefan-Olt/vs-plugin-build)**Cross-platform VapourSynth plugins

Scripts/download-deps-macos.sh

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# - yuygfgg/Macos_vapoursynth_plugins (https://github.com/yuygfgg/Macos_vapoursynth_plugins)
88
# - neo_f3kdb, dfttest, fftw libraries
99
# - Stefan-Olt/vs-plugin-build (https://github.com/Stefan-Olt/vs-plugin-build)
10-
# - FFMS2
10+
# - pipe_source.py (raw frame reader for VapourSynth)
1111
#
1212
# Prerequisites:
1313
# - Homebrew (for build tools only, not runtime)
@@ -362,38 +362,6 @@ if [ "$ARCH" = "arm64" ]; then
362362
echo " Downloaded pre-built ARM64 plugins from yuygfgg"
363363
fi
364364

365-
# ============================================================================
366-
# Download FFMS2 (fast source filter — packet-level indexing, no full decode)
367-
# ============================================================================
368-
echo ""
369-
echo "=== Downloading FFMS2 ==="
370-
371-
FFMS2_TAG="ffms2-257712fe8f3f103bfc94d236e8efb02dd18f1bcd"
372-
FFMS2_URL="https://github.com/Stefan-Olt/vs-plugin-build/releases/download/$FFMS2_TAG/FFmpegSource2-5.0-darwin-aarch64.zip"
373-
if [ "$ARCH" = "x86_64" ]; then
374-
FFMS2_TAG="ffms2-fb5016322ab87a120fcc750c6571e4cf5c9e1a5e"
375-
FFMS2_URL="https://github.com/Stefan-Olt/vs-plugin-build/releases/download/$FFMS2_TAG/FFmpegSource2-5.0-darwin-x86_64.zip"
376-
fi
377-
378-
if [ "$FORCE" = true ] || [ ! -f "$PLUGINS_DIR/libffms2.dylib" ]; then
379-
curl -sL "$FFMS2_URL" -o "$BUILD_DIR/ffms2.zip"
380-
unzip -q -o "$BUILD_DIR/ffms2.zip" -d "$BUILD_DIR/ffms2"
381-
382-
# Find and copy the dylib
383-
find "$BUILD_DIR/ffms2" -name "*.dylib" -exec cp {} "$PLUGINS_DIR/libffms2.dylib" \;
384-
385-
# Remove unused X11 dependency (transitive from FFmpeg build, not actually used)
386-
install_name_tool -change "/opt/homebrew/opt/libx11/lib/libX11.6.dylib" "/usr/lib/libSystem.B.dylib" "$PLUGINS_DIR/libffms2.dylib" 2>/dev/null || true
387-
388-
# Fix paths and sign
389-
install_name_tool -id "@loader_path/libffms2.dylib" "$PLUGINS_DIR/libffms2.dylib" 2>/dev/null || true
390-
codesign -s - -f "$PLUGINS_DIR/libffms2.dylib" 2>/dev/null
391-
392-
echo " Downloaded FFMS2"
393-
else
394-
echo " FFMS2 already exists, skipping"
395-
fi
396-
397365
# ============================================================================
398366
# Build plugins from source
399367
# ============================================================================

Scripts/download-deps-windows.ps1

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
- VapourSynth R73 (portable, includes Python 3.8)
88
- Python 3.8 embeddable (for VSScript)
99
- FFmpeg (latest GPL build)
10-
- VapourSynth plugins (FFMS2, mvtools, nnedi3cl, znedi3, eedi3m, fmtconv, miscfilters, dfttest, neo_f3kdb, cas, fft3dfilter)
10+
- VapourSynth plugins (mvtools, nnedi3cl, znedi3, eedi3m, fmtconv, miscfilters, dfttest, neo_f3kdb, cas, fft3dfilter)
1111
- FFTW library (required by dfttest)
1212
- Python packages (havsfunc, mvsfunc, adjust)
1313
- NNEDI3 weights
@@ -197,11 +197,6 @@ $Plugins7z = @(
197197
Url = "https://github.com/HomeOfVapourSynthEvolution/VapourSynth-EEDI3/releases/download/r8/EEDI3-r8.7z"
198198
Check = "EEDI3m.dll"
199199
},
200-
@{
201-
Name = "FFMS2"
202-
Url = "https://github.com/FFMS/ffms2/releases/download/5.0/ffms2-5.0-msvc.7z"
203-
Check = "ffms2.dll"
204-
},
205200
@{
206201
Name = "miscfilters"
207202
Url = "https://github.com/vapoursynth/vs-miscfilters-obsolete/releases/download/R2/miscfilters-r2.7z"

app/test/vapoursynth_integration_test.dart

Lines changed: 11 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import 'package:path/path.dart' as path;
1111
void main() {
1212
late String depsDir;
1313
late String vspipePath;
14-
late String testVideoPath;
1514

1615
setUpAll(() async {
1716
// Find the deps directory relative to the test file
@@ -46,21 +45,7 @@ void main() {
4645
}
4746
}
4847

49-
vspipePath = Platform.isWindows
50-
? path.join(depsDir, 'vapoursynth', vspipeExe)
51-
: path.join(depsDir, 'vapoursynth', vspipeExe);
52-
53-
// Create a simple test video (Y4M format - raw YUV)
54-
testVideoPath = path.join(Directory.systemTemp.path, 'vapourbox_test.y4m');
55-
await _createTestVideo(testVideoPath);
56-
});
57-
58-
tearDownAll(() async {
59-
// Clean up test video
60-
final testFile = File(testVideoPath);
61-
if (await testFile.exists()) {
62-
await testFile.delete();
63-
}
48+
vspipePath = path.join(depsDir, 'vapoursynth', vspipeExe);
6449
});
6550

6651
group('VapourSynth Plugin Loading', () {
@@ -76,7 +61,7 @@ import vapoursynth as vs
7661
core = vs.core
7762
7863
# List all required plugins (core set that works on both Windows and macOS)
79-
required = ['std', 'resize', 'bs', 'mv', 'znedi3', 'eedi3m', 'fmtc',
64+
required = ['std', 'resize', 'mv', 'znedi3', 'eedi3m', 'fmtc',
8065
'dfttest', 'neo_f3kdb', 'cas', 'dctf', 'deblock', 'rgvs',
8166
'ctmf', 'warp', 'misc', 'grain', 'tcanny']
8267
@@ -97,33 +82,13 @@ else:
9782
});
9883
});
9984

100-
group('FFMS2 Video Loading', () {
101-
test('loads video with FFMS2', () async {
102-
final script = '''
103-
import vapoursynth as vs
104-
core = vs.core
105-
106-
clip = core.ffms2.Source(source=r"$testVideoPath")
107-
print(f"Loaded: {clip.width}x{clip.height}, {clip.num_frames} frames")
108-
109-
# Output a single frame to verify it works
110-
clip = clip[0]
111-
clip.set_output()
112-
''';
113-
114-
final result = await _runVspipeScript(vspipePath, script, outputFrames: true);
115-
expect(result.exitCode, 0, reason: 'stderr: ${result.stderr}');
116-
expect(result.stdout.toString(), contains('Loaded:'));
117-
});
118-
});
119-
12085
group('Filter Tests', () {
12186
test('Deband (neo_f3kdb) works', () async {
12287
final script = '''
12388
import vapoursynth as vs
12489
core = vs.core
12590
126-
clip = core.bs.VideoSource(source=r"$testVideoPath")
91+
clip = core.std.BlankClip(width=64, height=64, format=vs.YUV420P8, length=10, fpsnum=25, fpsden=1)
12792
clip = core.neo_f3kdb.Deband(clip, y=64, cb=64, cr=64)
12893
print("Deband applied successfully")
12994
clip = clip[0]
@@ -139,7 +104,7 @@ clip.set_output()
139104
import vapoursynth as vs
140105
core = vs.core
141106
142-
clip = core.bs.VideoSource(source=r"$testVideoPath")
107+
clip = core.std.BlankClip(width=64, height=64, format=vs.YUV420P8, length=10, fpsnum=25, fpsden=1)
143108
clip = core.dfttest.DFTTest(clip, sigma=10.0)
144109
print("DFTTest applied successfully")
145110
clip = clip[0]
@@ -155,7 +120,7 @@ clip.set_output()
155120
import vapoursynth as vs
156121
core = vs.core
157122
158-
clip = core.bs.VideoSource(source=r"$testVideoPath")
123+
clip = core.std.BlankClip(width=64, height=64, format=vs.YUV420P8, length=10, fpsnum=25, fpsden=1)
159124
clip = core.cas.CAS(clip, sharpness=0.5)
160125
print("CAS applied successfully")
161126
clip = clip[0]
@@ -171,8 +136,7 @@ clip.set_output()
171136
import vapoursynth as vs
172137
core = vs.core
173138
174-
clip = core.bs.VideoSource(source=r"$testVideoPath")
175-
# Simple MVTools test - analyze motion
139+
clip = core.std.BlankClip(width=64, height=64, format=vs.YUV420P8, length=10, fpsnum=25, fpsden=1)
176140
sup = core.mv.Super(clip)
177141
vectors = core.mv.Analyse(sup, isb=False)
178142
print("MVTools applied successfully")
@@ -189,8 +153,7 @@ clip.set_output()
189153
import vapoursynth as vs
190154
core = vs.core
191155
192-
clip = core.bs.VideoSource(source=r"$testVideoPath")
193-
# ZNEDI3 for field interpolation
156+
clip = core.std.BlankClip(width=64, height=64, format=vs.YUV420P8, length=10, fpsnum=25, fpsden=1)
194157
clip = core.znedi3.nnedi3(clip, field=1)
195158
print("ZNEDI3 applied successfully")
196159
clip = clip[0]
@@ -206,7 +169,7 @@ clip.set_output()
206169
import vapoursynth as vs
207170
core = vs.core
208171
209-
clip = core.bs.VideoSource(source=r"$testVideoPath")
172+
clip = core.std.BlankClip(width=64, height=64, format=vs.YUV420P8, length=10, fpsnum=25, fpsden=1)
210173
clip = core.eedi3m.EEDI3(clip, field=1)
211174
print("EEDI3 applied successfully")
212175
clip = clip[0]
@@ -222,7 +185,7 @@ clip.set_output()
222185
import vapoursynth as vs
223186
core = vs.core
224187
225-
clip = core.bs.VideoSource(source=r"$testVideoPath")
188+
clip = core.std.BlankClip(width=64, height=64, format=vs.YUV420P8, length=10, fpsnum=25, fpsden=1)
226189
clip = core.deblock.Deblock(clip, quant=25)
227190
print("Deblock applied successfully")
228191
clip = clip[0]
@@ -238,7 +201,7 @@ clip.set_output()
238201
import vapoursynth as vs
239202
core = vs.core
240203
241-
clip = core.bs.VideoSource(source=r"$testVideoPath")
204+
clip = core.std.BlankClip(width=64, height=64, format=vs.YUV420P8, length=10, fpsnum=25, fpsden=1)
242205
clip = core.tcanny.TCanny(clip, sigma=1.5, mode=0)
243206
print("TCanny applied successfully")
244207
clip = clip[0]
@@ -272,7 +235,7 @@ import vapoursynth as vs
272235
import havsfunc as haf
273236
core = vs.core
274237
275-
clip = core.bs.VideoSource(source=r"$testVideoPath")
238+
clip = core.std.BlankClip(width=64, height=64, format=vs.YUV420P8, length=10, fpsnum=25, fpsden=1)
276239
clip = haf.SMDegrain(clip, tr=1, thSAD=300)
277240
print("SMDegrain applied successfully")
278241
clip = clip[0]
@@ -285,28 +248,6 @@ clip.set_output()
285248
});
286249
}
287250

288-
/// Creates a simple Y4M test video (10 frames of 64x64 gray)
289-
Future<void> _createTestVideo(String outputPath) async {
290-
final file = File(outputPath);
291-
final sink = file.openWrite();
292-
293-
// Y4M header
294-
sink.write('YUV4MPEG2 W64 H64 F25:1 Ip A1:1 C420\n');
295-
296-
// 10 frames of gray
297-
for (int frame = 0; frame < 10; frame++) {
298-
sink.write('FRAME\n');
299-
// Y plane (64x64 = 4096 bytes) - gray value 128
300-
sink.add(List.filled(64 * 64, 128));
301-
// U plane (32x32 = 1024 bytes) - neutral chroma
302-
sink.add(List.filled(32 * 32, 128));
303-
// V plane (32x32 = 1024 bytes) - neutral chroma
304-
sink.add(List.filled(32 * 32, 128));
305-
}
306-
307-
await sink.close();
308-
}
309-
310251
/// Runs a VapourSynth script via vspipe
311252
Future<ProcessResult> _runVspipeScript(
312253
String vspipePath,
-24.5 MB
Binary file not shown.

docs/BUILDING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ VapourBox bundles all runtime dependencies. No external installations are requir
177177
| VapourSynth | R73 | Video processing framework |
178178
| FFmpeg | Latest | Video encoding/decoding |
179179
| havsfunc | Latest | QTGMC implementation |
180-
| FFMS2 | 5.0 | Source filter for preview |
180+
| pipe_source.py | - | Raw frame reader for VapourSynth |
181181
| mvtools | v24 | Motion estimation |
182182
| znedi3 | Latest | Neural network interpolation |
183183
| EEDI3m | r8 | Edge-directed interpolation |

0 commit comments

Comments
 (0)