# oxideav-basic
Simple standard codecs and containers for oxideav (PCM, WAV, ...)
Part of the [oxideav](https://github.com/OxideAV/oxideav-workspace) framework — a pure-Rust media transcoding and streaming stack. Codec, container, and filter crates are implemented from the spec (no C codec libraries linked or wrapped, no `*-sys` crates). Optional hardware-engine crates (`oxideav-videotoolbox` / `-audiotoolbox` / `-vaapi` / `-vdpau` / `-nvidia` / `-vulkan-video`) bridge to OS APIs via runtime `libloading`; pass `--no-hwaccel` (or omit the `hwaccel` feature) to opt out.
## What's included
- **PCM codecs**: `pcm_u8`, `pcm_s16le`, `pcm_s24le`, `pcm_s32le`, `pcm_f32le`,
`pcm_f64le`.
- **WAV** container: RIFF/WAVE demuxer + muxer with `fmt`, `data`, and
`LIST/INFO` metadata. Dispatches `WAVE_FORMAT_ALAW (0x0006)` /
`WAVE_FORMAT_MULAW (0x0007)` to the `pcm_alaw` / `pcm_mulaw` codecs
(host runtime applies G.711 decode). `WAVE_FORMAT_EXTENSIBLE (0xFFFE)`
is parsed end-to-end — the 22-byte extension's `wValidBitsPerSample`,
`dwChannelMask` and SubFormat GUID are surfaced through both
`wav:fmt.*` metadata keys and typed accessors on the concrete
`WavDemuxer`. Well-known `KSDATAFORMAT_SUBTYPE_*` GUIDs (PCM,
IEEE_FLOAT, ALAW, MULAW) resolve to the same codec ids the legacy
`WAVEFORMATEX` path would have produced; unknown GUIDs synthesise a
`wav:guid_<canonical-text>` id. `WavMuxOptions::with_extensible(mask)`
opts the muxer into writing a 40-byte EXTENSIBLE `fmt ` chunk. The
`bext` Broadcast Audio Extension chunk (EBU Tech 3285) is parsed and
surfaced through `wav:bext.*` metadata keys — description, originator,
origination date/time, 64-bit `TimeReference`, BWF version, SMPTE-330M
UMID (v1+) and the v2 loudness fields (`LoudnessValue`,
`LoudnessRange`, `MaxTruePeakLevel`, `MaxMomentaryLoudness`,
`MaxShortTermLoudness`, each ×100 fixed-point rendered to two
decimals) plus `CodingHistory`. The `cue ` chunk, `plst` (Playlist)
chunk and `LIST adtl` (Associated Data List) sub-chunks are parsed
per Microsoft RIFF MCI §3 — cue points surface as `wav:cue.count`
plus per-point `wav:cue.<dwName>.position` / `.fcc_chunk` /
`.chunk_start` / `.block_start` / `.sample_offset`; playlist
segments surface as `wav:plst.count` plus per-segment
`wav:plst.<n>.cue_id` / `.length` / `.loops` (zero-based segment
index `<n>` because a single cue id can be replayed by multiple
playlist entries); `labl` / `note` text sub-chunks surface as
`wav:adtl.labl.<dwName>` / `wav:adtl.note.<dwName>`; the `ltxt`
(text-with-segment-length) sub-chunk surfaces as
`wav:adtl.ltxt.<dwName>.length` / `.purpose` (FOURCC) / `.text`. The
`smpl` (Sampler) and `inst` (Instrument) chunks surface through
`wav:smpl.*` (manufacturer / product / sample_period / midi_unity_note
/ midi_pitch_fraction / smpte_format / smpte_offset rendered as
`HH:MM:SS:FF` / sampler_data_len / num_sample_loops + per-loop
`wav:smpl.loop.<n>.{cue_point_id,type,start,end,fraction,play_count}`)
and `wav:inst.{unshifted_note,fine_tune,gain,low_note,high_note,
low_velocity,high_velocity}` (signed `fine_tune` / `gain` decoded as
`i8`). Loop counts that exceed the chunk body are clamped; bodies
shorter than the 36-byte `smpl` / 7-byte `inst` fixed header are
treated as opaque.
- **slin** container: Asterisk-style headerless `.sln*` / `.slin*` raw
S16LE PCM (extension drives the sample rate).
- **Y4M (YUV4MPEG2)** container: rawvideo demuxer + muxer for `.y4m` files,
supporting 4:2:0 / 4:2:2 / 4:4:4 / mono at 8/10/12-bit. Header `X<key>=<val>`
extensions are surfaced verbatim through `Demuxer::metadata`.
## Usage
```toml
[dependencies]
oxideav-basic = "0.0"
```
## License
MIT — see [LICENSE](LICENSE).