mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-12 10:03:51 +00:00
* craft-audio: Opus decoder FilmCraft's `filmcraft-opus` decoder as `craft_audio::opus` behind `opus-decode`: SILK, hybrid and CELT, every frame size, PLC and FEC, multistream (`Decoder`) and single stream (`StreamDecoder`), 8-48 kHz output. - `TrackDecoder` decodes Opus; mono and stereo without an `OpusHead` (RTP, MPEG-TS) get a default one. Lost packets use Opus's own concealment. - The native read path takes Ogg Opus (pre-skip and end trimming per RFC 7845), and Opus in Matroska/WebM and MP4, where packet starts after a seek come from the packets' own lengths. The RFC 8251 conformance test runs all 36 vectors. `scripts/fetch-opus-vectors.sh` downloads them (SHA-256 checked) and the CI test job caches them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * craft-audio: review fixes, round 1 (#445) - CELT concealment keeps its pitch in its own field. It reused postfilter_period_old, which the next good frame's post-filter cross-fades from. - Matroska Opus seeks: a failed packet read no longer caches a wrong start; a one-byte packet is read as one byte. - A malformed OpusHead in Ogg is reported as malformed instead of falling back. - The libopus oracle tests skip through the testkit, so CRAFT_MEDIA_REQUIRE_ORACLES fails them. - Decoder::reset documents that it re-arms pre-skip trimming. - fetch-opus-vectors.sh retries its size probe. - CI: the vectors are fetched after ffmpeg is installed, and apt's timeout runs as root so a stalled apt-get is killed and frees the dpkg lock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * craft-audio: review fixes, round 2 (#445) - CELT: the noise-based concealment sets skip_plc, as libopus does, so pitch-based concealment waits for two good frames in a row instead of extending history that holds noise. - SILK: decode_only_middle is per call, as in libopus. A lost or mono frame no longer reuses the mid-only flag from an earlier frame. - A damaged Opus packet is concealed at its own length (from its TOC and framing) rather than the previous packet's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Dylan M. Taylor <dylan@dylanmtaylor.com>
67 lines
2.5 KiB
Bash
Executable File
67 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Fetch the Opus RFC 8251 conformance vectors (opus_testvectors-rfc8251, 75 MB) into DIR
|
|
# (default target/fixtures/opus/vectors), checked against their SHA-256. craft-audio's Opus
|
|
# conformance test reads them from there; they are test data, never committed.
|
|
#
|
|
# The archive is fetched in parallel byte ranges, and a range whose connection slows to a crawl is
|
|
# dropped and fetched again: opus-codec.org throttles some connections to a few KB/s.
|
|
set -euo pipefail
|
|
|
|
URL=https://opus-codec.org/static/testvectors/opus_testvectors-rfc8251.tar.gz
|
|
SHA256=6b26a22f9ba87b2b836906a9bb7afec5f8e54d49553b1200382520ee6fedfa55
|
|
DEST=${1:-target/fixtures/opus/vectors}
|
|
|
|
if [ -f "$DEST/testvector01.bit" ] && [ -f "$DEST/testvector12m.dec" ]; then
|
|
echo "Opus vectors already in $DEST"
|
|
exit 0
|
|
fi
|
|
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
|
|
len=$(curl -fsSIL --retry 10 --retry-delay 2 --retry-all-errors --connect-timeout 20 --max-time 60 "$URL" | tr -d '\r' | awk 'tolower($1) == "content-length:" { n = $2 } END { print n }')
|
|
[ -n "$len" ] || { echo "could not read the archive size" >&2; exit 1; }
|
|
|
|
# Small ranges, eight at a time: a range whose connection drops below 50 KB/s for 15 s is
|
|
# abandoned and fetched again, which costs little for a 2 MB range.
|
|
chunk=2000000
|
|
ranges=()
|
|
for ((start = 0; start < len; start += chunk)); do
|
|
end=$((start + chunk - 1))
|
|
((end < len)) || end=$((len - 1))
|
|
ranges+=("$start-$end")
|
|
done
|
|
fetch() { # fetch RANGE PART
|
|
curl -fsS --retry 20 --retry-delay 1 --retry-all-errors --speed-limit 50000 --speed-time 15 -r "$1" -o "$2" "$URL"
|
|
}
|
|
export -f fetch
|
|
export URL
|
|
for i in "${!ranges[@]}"; do
|
|
printf '%s %s/part.%04d\n' "${ranges[$i]}" "$tmp" "$i"
|
|
done | xargs -P 8 -n 2 bash -c 'fetch "$0" "$1"' || true
|
|
# Fetch again any range that came back short, one at a time.
|
|
for attempt in 1 2 3 4 5; do
|
|
short=0
|
|
for i in "${!ranges[@]}"; do
|
|
range=${ranges[$i]}
|
|
want=$((${range#*-} - ${range%-*} + 1))
|
|
part=$(printf '%s/part.%04d' "$tmp" "$i")
|
|
if [ "$(wc -c < "$part" 2> /dev/null || echo 0)" -ne "$want" ]; then
|
|
short=1
|
|
fetch "$range" "$part" || true
|
|
fi
|
|
done
|
|
[ "$short" -eq 0 ] && break
|
|
done
|
|
cat "$tmp"/part.* > "$tmp/vectors.tar.gz"
|
|
|
|
if command -v sha256sum > /dev/null; then
|
|
echo "$SHA256 $tmp/vectors.tar.gz" | sha256sum -c -
|
|
else
|
|
echo "$SHA256 $tmp/vectors.tar.gz" | shasum -a 256 -c -
|
|
fi
|
|
|
|
mkdir -p "$DEST"
|
|
tar xzf "$tmp/vectors.tar.gz" -C "$DEST" --strip-components=1
|
|
echo "Opus vectors in $DEST"
|