# PixelFlow

PixelFlow is a Rust-first video processing framework.
It is currently in Phase 1 of development, which establishes cross-platform core foundations,
scripting, plugin, source, filter, CLI, and embedding workflows.

## Workspace

This repository uses Rust edition 2024 and MSRV 1.88+.

Initial crates:

- `pixelflow-core`: shared core abstractions.
- `pixelflow-plugin-sdk`: Rust plugin authoring API.
- `pixelflow-script`: script integration layer.
- `pixelflow-filters`: official in-repo filters, including FFMS2 source plugin.
- `pixelflow-cli`: command-line entry point.
- `pixelflow`: public facade crate.

## Development

Run local quality gates before opening merge requests:

```bash
cargo fmt --all --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-features
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps
```

### FFMS2 Source Development

`pixelflow-filters` links against system FFMS2 through Rust `ffms2` crate. Install FFMS2 headers/libraries and libclang before running all-feature builds.

Linux example:

```bash
apt-get install clang libclang-dev pkg-config libffms2-dev libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev
```

Windows CI downloads cached prebuilt Gyan FFmpeg full shared and official FFMS2 Windows releases into `.ci-deps`, sets `FFMPEG_DIR`, `FFMS_INCLUDE_DIR`, `FFMS_LIB_DIR`, and `LIBCLANG_PATH`, and keeps the FFmpeg/FFMS2 DLL directories on `PATH` for native binding crates.

## Plugin ABI

- Rust SDK is Phase 1 official plugin authoring path.
- Generated C header lives at `crates/pixelflow-plugin-sdk/include/pixelflow_plugin.h` for ABI stability review.
- Direct C/C++ plugin authoring is unsupported in Phase 1.
- Versioned plugin entry symbol is `pixelflow_plugin_entry_v1`.
- `Core` auto-loads plugins from conventional platform directories during construction.
- Plugin load or registration failures warn and are skipped without blocking built-in filters.

## Script Filter Calls

Scripts use `source("path")` for FFMS2-backed video sources in CLI. Registered filters can be called through generic `filter(...)` API or namespace sugar:

```rhai
clip = source("input.mkv", #{ cache: "input.pfidx" })
output = plugin.acme.blur(clip, #{ radius: 2 })
```

Built-in standard-library filters are registered under `std` plugin namespace and can use shorter `std.<filter>(...)` form:

```rhai
y = source("input.mkv").std.split_plane(#{ plane: 0 })
u = source("input.mkv").std.split_plane(#{ plane: 1 })
v = source("input.mkv").std.split_plane(#{ plane: 2 })
output = std.merge_planes([y, u, v], #{ format: "yuv420p8" })
```

Method-chain forms are also supported when filter consumes one clip:

```rhai
output = source("input.mkv")
    .std.resize(#{ width: 1280, height: 720 })
    .plugin.acme.blur(#{ radius: 2 })
```

Descriptor-only third-party filters currently plan as opaque custom filters that preserve first-input media during graph construction. Rendering third-party filter executors still needs future plugin ABI support.

## License

PixelFlow and official in-repo plugins are licensed under either of:

- Apache License, Version 2.0, in `LICENSE-APACHE`
- MIT license, in `LICENSE-MIT`

at your option.
