mirror of
https://github.com/freemkv/libfreemkv.git
synced 2026-10-07 18:13:10 +00:00
libfreemkv::spec holds the verbatim specification quotes the code cites, with guards tying each governed site to its quote. A test-util feature exposes shared fixtures to downstream tests. M2TS output derives DTS for reordered video and rounds to whole 90 kHz ticks.
146 lines
6.5 KiB
TOML
146 lines
6.5 KiB
TOML
[package]
|
|
name = "libfreemkv"
|
|
version = "1.7.7"
|
|
edition = "2024"
|
|
rust-version = "1.88"
|
|
license = "MIT"
|
|
description = "Open source raw disc access library for optical drives"
|
|
repository = "https://github.com/freemkv/libfreemkv"
|
|
keywords = ["bluray", "uhd", "optical", "scsi", "disc"]
|
|
categories = ["hardware-support", "multimedia"]
|
|
# Keep internal AI-instruction / private notes out of the published crate.
|
|
exclude = ["CLAUDE.md"]
|
|
# OFF crates.io: libfreemkv git-deps freemkv-unlock (firmware, never published),
|
|
# so libfreemkv itself can only be consumed by git tag. Clients git-tag-pin it.
|
|
publish = false
|
|
|
|
[profile.release]
|
|
lto = "thin"
|
|
codegen-units = 1
|
|
|
|
# ── Feature layout ───────────────────────────────────────────────────────────
|
|
# `scsi` — the SCSI passthrough transport layer ONLY (`src/scsi/` + `error`):
|
|
# ScsiTransport/execute, ScsiResult/ScsiSense/parse_sense, DriveInfo,
|
|
# list_drives, drive_has_disc, CDB builders, the per-OS backends and
|
|
# the raw-`cc` macOS shim (built by build.rs). Pulls only `tracing`
|
|
# (transport instrumentation) plus the always-on `libc` target dep —
|
|
# none of the ripping dependency tree.
|
|
# `rip` — the full ripping tree (drive lifecycle, disc/UDF/MPLS/CLPI parsing,
|
|
# AACS/CSS decrypt, PES/mux pipeline, keydb, freemkv-unlock seam). All
|
|
# heavy deps (serde, zip, rayon, roxmltree, rand, crossbeam, memchr,
|
|
# sha1, aes, base64, freemkv-unlock, serde_json) live here.
|
|
# `default = ["rip", "scsi"]` preserves today's full build byte-for-byte;
|
|
# consumers wanting transport only use `default-features = false, features =
|
|
# ["scsi"]`. `rip` implies `scsi` because the ripping tree reads through it.
|
|
[features]
|
|
default = ["rip", "scsi"]
|
|
scsi = ["dep:tracing"]
|
|
rip = [
|
|
"scsi",
|
|
"dep:serde",
|
|
"dep:serde_json",
|
|
"dep:sha1",
|
|
"dep:aes",
|
|
"dep:freemkv-unlock",
|
|
"dep:zip",
|
|
"dep:base64",
|
|
"dep:roxmltree",
|
|
"dep:crossbeam-channel",
|
|
"dep:rayon",
|
|
"dep:memchr",
|
|
"dep:socket2",
|
|
"dep:rustix",
|
|
]
|
|
# `test-util`: `libfreemkv::test_util` fixtures for consumers' tests (dev-dependency
|
|
# only; never in a release build). Implies the rip tree the fixtures build on.
|
|
test-util = ["rip"]
|
|
|
|
[dependencies]
|
|
serde = { version = "1", features = ["derive"], optional = true }
|
|
serde_json = { version = "1", optional = true }
|
|
sha1 = { version = "0.11", optional = true }
|
|
aes = { version = "0.9", optional = true }
|
|
# Interim path dep for local cross-repo dev; `release-orchestrate.yml` re-pins
|
|
# this to `{ git = ".../freemkv-unlock", tag = "vX.Y.Z" }` in the tagged commit
|
|
# (so the released tag resolves freemkv-unlock from git, not a sibling path) and
|
|
# restores the path dep on the branch tip.
|
|
freemkv-unlock = { path = "../freemkv-unlock", optional = true }
|
|
zip = { version = "8", default-features = false, features = ["deflate"], optional = true }
|
|
base64 = { version = "0.23", optional = true }
|
|
# Safe TCP keepalive setup for `network://` receive (dead-peer detection);
|
|
# `all` provides TcpKeepalive::with_retries.
|
|
socket2 = { version = "0.6", features = ["all"], optional = true }
|
|
# Safe readiness poll (poll/WSAPoll) so a halt-aware `network://` receive never
|
|
# arms SO_RCVTIMEO, which on Windows can drop data when it cancels a recv.
|
|
rustix = { version = "1", default-features = false, features = ["std", "event"], optional = true }
|
|
# Read-only XML DOM parser (pure Rust, forbid(unsafe_code), entity-expansion
|
|
# bounded). Parses the HD-DVD Advanced-Content playlist `ADV_OBJ/VPLST000.XPL`
|
|
# — untrusted disc bytes — into authoritative titles/clips/chapters. A real
|
|
# parser, not a hand-rolled scanner: the XPL is genuine XML (comments, varied
|
|
# attribute order, self-closing tags).
|
|
roxmltree = { version = "0.20", optional = true }
|
|
# Trace-level instrumentation for the read/transport path (SgIoTransport::execute
|
|
# and friends). Part of the `scsi` feature — the transport layer traces here.
|
|
# Permitted
|
|
# under CLAUDE.md ("Acceptable strings: debug/trace logging"). Consumers (autorip)
|
|
# wire a tracing subscriber and pipe events into the JSONL debug log.
|
|
tracing = { version = "0.1", optional = true }
|
|
# Bounded MPSC channel with kernel-wakeup send_timeout. Used by `io::pipeline`
|
|
# so the halt-aware send/finish loops can BLOCK on consumer drain instead of
|
|
# polling — the 50 ms poll cadence of the previous mpsc-based impl capped mux
|
|
# throughput at ~1 MB/s (0.21.7).
|
|
crossbeam-channel = { version = "0.5", optional = true }
|
|
# Persistent work-stealing thread pool for parallel AACS unit
|
|
# decryption. Per-call std::thread::scope spawned fresh OS threads
|
|
# and that overhead dominated for typical batch sizes (60 units).
|
|
# rayon's global pool initialises once on first use.
|
|
rayon = { version = "1", optional = true }
|
|
# SIMD-accelerated bytestring search. Drives the HEVC/H.264 start-code
|
|
# scan in `mux::codec::h264::find_start_code` — naive byte-by-byte
|
|
# walk is ~500 MB/s single-thread on x86_64; memchr's vectorised
|
|
# `memmem::find` for the 3-byte `00 00 01` needle hits ~5 GB/s on
|
|
# AVX2-capable hosts.
|
|
memchr = { version = "2", optional = true }
|
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
libc = "0.2"
|
|
|
|
[target.'cfg(target_os = "macos")'.dependencies]
|
|
libc = "0.2"
|
|
|
|
[dev-dependencies]
|
|
tempfile = "3"
|
|
|
|
# Permutation model checker for the `scsi::fd_handoff` atomics — the fd
|
|
# hand-off between a Linux recovery thread and `SgIoTransport::drop`. A normal
|
|
# test cannot see a missing release edge there: the orderings compile to the
|
|
# same instructions on x86_64, so the wrong ones pass every time. loom
|
|
# enumerates the executions the C++20 model permits and reports the leaked
|
|
# descriptor directly.
|
|
#
|
|
# Behind `cfg(loom)`, which nothing sets unless you ask for it, so this is out
|
|
# of the graph for every ordinary build and for every CI job but the dedicated
|
|
# `loom` one. Run it with:
|
|
#
|
|
# RUSTFLAGS="--cfg loom" cargo test --lib --no-default-features \
|
|
# --features scsi fd_handoff
|
|
#
|
|
# `cargo test --lib` specifically: as a DEV-dependency loom is only in scope for
|
|
# test targets, which is why `fd_handoff` gates its import on `all(loom, test)`
|
|
# and falls back to std elsewhere. Without that, `--cfg loom` would break plain
|
|
# `cargo build`/`clippy` with an unresolved-crate error.
|
|
[target.'cfg(loom)'.dev-dependencies]
|
|
loom = "0.7"
|
|
|
|
[[bench]]
|
|
name = "sgio_read"
|
|
harness = false
|
|
|
|
|
|
[lints.rust]
|
|
# `loom` is set by RUSTFLAGS for the model checker above, never by a feature.
|
|
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(loom)'] }
|
|
|
|
[lints.clippy]
|
|
uninlined_format_args = "allow"
|