mediaway 0.1.1

Convenience pipeline layer — composes encoder + container (+ device capture)
# mediaway — roadmap

**Facade-of-facades** crate (composition only, no traits of its own).
Packaging: [`docs/spec/crate-packaging.md`](../../../docs/spec/crate-packaging.md).
Workspace index: [`docs/roadmap.md`](../../../docs/roadmap.md).

## Stages

### 0 — Scaffold

- [x] Crate + `docs/` / `adr/`
- [x] Workspace ADR-0014: crate exists, `EncodeSession` shape, platform dispatch migration
- [x] `EncodeSession<E: VideoEncoder>` — open / write_frame / finish
- [x] `platform` module — `AutoEncoder`/`AutoDecoder`/`ScreenCapture`/`Microphone`
      marker types, each with an `open` associated function (migrated from
      `examples/platform.rs`; renamed from free functions 2026-07-31, see ADR-0014's
      addendum — `screen_config` dropped as a duplicate of
      `VideoCaptureConfig::screen`)
- [x] `PipelineError` (`thiserror`, wraps `EncodeError` + container `Error`)

### 1 — Windows

- [x] `AutoVideoEncoder` (unboxed) and `Box<dyn VideoEncoder>` both work with `EncodeSession`
- [x] Screen-record composed through this crate end-to-end (`platform::ScreenCapture::open`
      + `platform::Microphone::open` + `platform::AutoEncoder::open` DX11 Zero-Copy H.264 +
      `WindowsAudioEncoder` AAC → shared two-track `mediaway_container::mp4::Muxer`) —
      `tests/screen_mic_av_smoke.rs`. `EncodeSession` itself stays untouched (see 1b); the
      second track is composed directly against the muxer, mirroring
      `mediaway-encoder-windows/tests/av_fmp4_smoke.rs`
- [x] Decode → trim → splice → re-encode round trip through real mux/demux —
      `tests/trim_and_splice_windows.rs` + `examples/pipeline/trim_and_splice.rs`; this is what
      surfaced and drove the AVCC/Annex-B extradata fix in `mediaway-decoder-windows`
      ADR-0001 (demuxed samples are AVCC-framed, encoder/decoder MFTs expect Annex-B)

### 1b — Audio / multi-track — done (2026-08-01)

- [x] `EncodeSession` extension for a second (audio) track —
      [ADR-0003]../adr/0003-audio-track-and-apm-integration.md: `open_with_audio`,
      `write_audio_frame`/`write_audio_render_frame`, `finish()` flushes both tracks
- [x] Optional `mediaway-audio-apm` (AEC3+NS+AGC2 `AudioProcessor`, RNN
      `VoiceActivityDetector`) wiring — `attach_audio_processor`/`attach_vad`,
      `poll_vad_score`; unit-tested with synthetic PCM (`src/session_tests.rs`), no real
      mic needed
- [ ] Migrate `tests/screen_mic_av_smoke.rs` off its hand-rolled second-track muxing
      onto `EncodeSession::open_with_audio` directly (now possible, not yet done)

### 2 — Web / 3 — Linux / 4 — Other

- [x] `ScreenCapture::open` Linux dispatch — `mediaway-device-linux` existed as
      a workspace member with a real `LinuxScreenCapture` backend, but was
      never added as a pipeline dependency nor wired into `platform.rs`'s
      `#[cfg(...)]` dispatch; this was a real, pre-existing gap (not a
      not-yet-landed backend) — fixed this session, verified via WSL2
      (`cargo build`/`test`/`clippy -p mediaway`, real Linux target)
- [ ] Extend `platform` dispatch as remaining backends (Web, camera, audio on
      Linux) land, following the workspace platform order

### 5 — Device capability / permission dispatch

- [x] `platform::device_support` / `platform::request_device_permission`      `#[cfg]` dispatch to `mediaway-device-windows`/`-linux`
      `capabilities::{support, request_permission}`, mirroring
      `ScreenCapture::open`'s pattern (see `mediaway-device` ADR-0003)

### 6 — Mid-pipeline frame filter hook

- [x] `FrameFilter` trait + `FilterError` (`src/filter.rs`), `EncodeSession::filters`
      (`SmallVec<[Box<dyn FrameFilter>; 4]>`) and `push_filter` (`src/session.rs`),
      `PipelineError::Filter(#[from] FilterError)` — additive, `open`/`write_frame`
      signatures unchanged; v1 is CPU-frame-only, `Gpu`-backed frames + a non-empty
      chain fail loudly with `FilterError::GpuFrameUnsupported` (see
      [ADR-0001]../adr/0001-frame-filter-hook.md)