Open source

FFmpeg and dav1d source

Astrape uses FFmpeg and dav1d. This page has their exact source code, the build script and the licence texts, and tells you how to rebuild the framework and put your own in the app.

What Astrape uses

FFmpeg is a separate dynamic framework, FFmpeg.framework, embedded in the app. FFmpeg and dav1d are built as static libraries and linked into that one framework, so you can replace it with your own build. It has a tvOS device slice and a simulator slice, both arm64, for tvOS 18.0 and later.

No patches. The two archives below are the upstream releases, unchanged, and the build script applies no patch to them.

Files

Everything is here, with its size and SHA-256. Check the files with shasum -a 256 -c SHA256SUMS.

FileBytesSHA-256
ffmpeg-7.1.tar.bz2
FFmpeg 7.1 source, as released by ffmpeg.org
13,260,188fd59e6160476095082e94150ada5a6032d7dcc282fe38ce682a00c18e7820528
dav1d-1.5.1.tar.xz
dav1d 1.5.1 source, as released by VideoLAN
1,020,760401813f1f89fa8fd4295805aa5284d9aed9bc7fc1fdbe554af4292f64cbabe21
build_ffmpeg.sh
The build script, exactly as used
23,47732b76494eaec11f22951679d6d1f5575e0660477e1eaaf2867bc40d86f766203
FFmpeg.PrivacyInfo.xcprivacy
The Apple privacy manifest the build script copies into the framework
8178f564a0be42e1bd1c0f9b2b89c5a72dbdbeaadb1e284bce8b855fa5bb99a1881
COPYING.LGPLv2.1
FFmpeg's licence, LGPL version 2.1
26,526b634ab5640e258563c536e658cad87080553df6f34f62269a21d554844e58bfe
dav1d-COPYING
dav1d's licence, BSD 2-Clause
1,317b327887de263238deaa80c34cdd2ff3e0ba1d35db585ce14a37ce3e74ee389e9
README.txt
The same facts as this page, as plain text
13,034212338cf779ff431f5a15d53650bccd04a23a65773e7cf8da89042b26787f06c
SHA256SUMS
The SHA-256 of every file above except itself
5876bf64fee9f4470f05164acb26bbd82565cb89c3f0bac099d21176db1f73e65ac

Configure flags

build_ffmpeg.sh passes these flags to FFmpeg's configure for both slices. They are the script's COMMON_FLAGS array, copied from it; --disable-gpl and --disable-nonfree are in the list.

--disable-everything
--disable-programs
--disable-doc
--disable-avdevice
--enable-avfilter              # only the deinterlacer, below
--disable-postproc
--disable-network
--disable-gpl
--disable-nonfree
--enable-pic
--enable-cross-compile
--target-os=darwin
--arch=arm64

# Containers we need to demux
--enable-demuxer=matroska      # MKV / WebM
--enable-demuxer=mov           # MP4 / MOV / M4V
--enable-demuxer=mpegts        # TS
--enable-demuxer=mpegps        # PS / VOB
--enable-demuxer=avi
--enable-demuxer=flv
--enable-demuxer=ogg
--enable-demuxer=asf
--enable-demuxer=rm
--enable-demuxer=concat        # virtual concat for segmented files
# Raw elementary-stream probes: MPEG-PS (VOB/MPG) identifies an H.264 /
# HEVC video stream only by probing its payload with these demuxers.
--enable-demuxer=h264
--enable-demuxer=hevc
--enable-demuxer=mpegvideo
--enable-demuxer=ivf           # raw AV1 / VP9 / VP8
--enable-demuxer=obu           # raw AV1

# Video the Apple TV can't decode in hardware: decoded here, encoded to
# HEVC by VideoToolbox (Core/Engine/Transcode).
--enable-libdav1d
--enable-decoder=libdav1d      # AV1
--enable-decoder=vp9
--enable-decoder=vp8
--enable-decoder=mpeg1video
--enable-decoder=mpeg2video
--enable-decoder=mpeg4         # MPEG-4 Part 2 (Xvid, DivX 4+)
--enable-decoder=msmpeg4v1
--enable-decoder=msmpeg4v2
--enable-decoder=msmpeg4v3     # DivX 3
--enable-decoder=h263
--enable-decoder=flv           # Sorenson H.263
--enable-decoder=vc1
--enable-decoder=wmv1
--enable-decoder=wmv2
--enable-decoder=wmv3
--enable-decoder=vp3
--enable-decoder=theora
--enable-decoder=mjpeg
--enable-decoder=prores
--enable-parser=av1
--enable-parser=vp9
--enable-parser=vp8
--enable-parser=mpegvideo
--enable-parser=mpeg4video
--enable-parser=h263
--enable-parser=vc1
--enable-parser=mjpeg
--enable-bsf=vp9_superframe_split   # the VP9 decoder needs it

# Audio decoders
--enable-decoder=ac3           # Dolby Digital
--enable-decoder=eac3          # Dolby Digital Plus (E-AC-3 + JOC/Atmos)
--enable-decoder=truehd        # TrueHD / MLP (see §8 license note)
--enable-decoder=mlp
--enable-decoder=dca           # DTS (see §8 license note — defer for App Store)
--enable-decoder=aac
--enable-decoder=aac_latm
--enable-decoder=mp3
--enable-decoder=mp2           # MPEG-1 Layer II: DVB recordings, VOB/MPG
--enable-decoder=mp2float
--enable-decoder=mp1
--enable-decoder=flac
--enable-decoder=opus
--enable-decoder=vorbis
--enable-decoder=alac
--enable-decoder=pcm_s16le
--enable-decoder=pcm_s16be
--enable-decoder=pcm_s24le
--enable-decoder=pcm_s24be
--enable-decoder=pcm_s32le
--enable-decoder=pcm_bluray    # lpcm in remux MKVs
--enable-decoder=pcm_dvd       # lpcm in VOB
--enable-decoder=pcm_u8        # old AVI
--enable-decoder=pcm_f32le
--enable-decoder=pcm_alaw
--enable-decoder=pcm_mulaw
--enable-decoder=adpcm_ms      # old AVI
--enable-decoder=adpcm_ima_wav
--enable-decoder=wmav1         # ASF / WMV audio
--enable-decoder=wmav2
--enable-decoder=wmapro

# Subtitle decoders
--enable-decoder=pgssub        # PGS (Blu-ray) — ubiquitous in remux MKVs
--enable-decoder=dvdsub        # VOBSUB
--enable-decoder=dvbsub
--enable-decoder=ass
--enable-decoder=ssa
--enable-decoder=srt
--enable-decoder=subrip
--enable-decoder=webvtt
--enable-decoder=mov_text
--enable-decoder=microdvd
--enable-decoder=text

# Parsers for audio + HEVC bitstream (NAL boundary detection, DTS detect)
--enable-parser=hevc           # HEVC NAL splitter — needed for RPU work
--enable-parser=h264
--enable-parser=ac3
--enable-parser=eac3
--enable-parser=dca
--enable-parser=aac
--enable-parser=aac_latm
--enable-parser=flac
--enable-parser=opus
--enable-parser=vorbis
--enable-parser=mpegaudio
--enable-parser=mlp

# Muxers — Path B remuxes demuxed packets into fragmented MP4 via movenc
# (DEMUX_ENGINE_PLAN.md §6.2 / Revision 2).  Without these, the
# avformat_alloc_output_context2(..., "mp4") call returns NULL and the whole
# Path B muxer fails to initialise.  movenc is LGPL-clean.
--enable-muxer=mov             # shared movenc core
--enable-muxer=mp4             # fragmented MP4 output (dvcC / dec3 / dac3)

# Bitstream filters.
#   hevc_mp4toannexb / h264_mp4toannexb — Path A's VTDecompressionSession
#     needs Annex-B; Path B keeps the native length-prefixed (MP4) framing.
#   extract_extradata — pull in-band VPS/SPS/PPS into codecpar->extradata.
--enable-bsf=hevc_mp4toannexb
--enable-bsf=h264_mp4toannexb
--enable-bsf=extract_extradata

# Encoders — TrueHD / DTS have no Apple TV passthrough path, so Path B
# decodes them to PCM and re-encodes to E-AC-3 (Revision 2 audio decision),
# which movenc then muxes with a dec3 box like native Dolby Digital Plus.
# Both encoders are FFmpeg-native and LGPL-clean (no GPL/libfdk dependency).
--enable-encoder=ac3
--enable-encoder=eac3

# Protocols — only file + custom (AVIOBridge). No network stacks from FFmpeg.
--enable-protocol=file
--enable-protocol=pipe
--enable-protocol=custom       # avio_alloc_context (our AVIOBridge)

# swresample for audio decode → PCM conversion
--enable-swresample

# Disable bitcode (dead since Xcode 14)
--disable-bzlib                # avoid dependency; unused

# Interlaced sources (DVD, broadcast MPEG-2 and VC-1) are deinterlaced
# before they are encoded: bwdif, one frame out per frame in.
--enable-filter=buffer
--enable-filter=buffersink
--enable-filter=bwdif

Each slice also passes the following (build_slice in build_ffmpeg.sh). SLICE_DIR is the slice's build folder, CC and AR are the SDK's clang and ar, SYSROOT is the SDK, and CFLAGS and LDFLAGS are "-arch arm64 -target TARGET_TRIPLE -isysroot SYSROOT". TARGET_TRIPLE is arm64-apple-tvos18.0 for the device and arm64-apple-tvos18.0-simulator for the simulator.

./configure \
    "${COMMON_FLAGS[@]}" \
    --pkg-config-flags="--static" \
    --prefix="${SLICE_DIR}/install" \
    --cc="${CC}" \
    --ar="${AR}" \
    --sysroot="${SYSROOT}" \
    --extra-cflags="${CFLAGS}" \
    --extra-ldflags="${LDFLAGS}" \
    --enable-static \
    --disable-shared \
    2>&1 | tail -20

dav1d is built as a static library with meson, using the options that build_dav1d in build_ffmpeg.sh passes. The same function writes the meson cross file, which sets the C compiler to clang with the same -arch, -target and -isysroot flags.

meson setup "${BUILD_DIR}/${SLICE}/dav1d-build" "${BUILD_DIR}/src/${DAV1D_SRC}" \
    --cross-file "${CROSS}" --prefix "${PREFIX}" --libdir lib \
    --buildtype release -Ddebug=true --default-library static \
    -Denable_tools=false -Denable_tests=false -Denable_examples=false

How to rebuild the framework

You need a Mac with Xcode 15 or later, the tvOS platform and SDK, the Command Line Tools, and four Homebrew packages:

brew install nasm pkg-config meson ninja
  1. Make a folder called Scripts, put build_ffmpeg.sh and FFmpeg.PrivacyInfo.xcprivacy in it, and run the script from the folder above it: bash Scripts/build_ffmpeg.sh. It downloads both archives (the dav1d one is checked against its SHA-256), builds the device and simulator slices, and writes build/xcframeworks/FFmpeg.xcframework.
  2. To build from the archives on this page instead of downloading them, extract them first into $TMPDIR/HDP_FFmpeg_Build/src/, so that ffmpeg-7.1/ and dav1d-1.5.1/ are there. The script uses a folder that already exists and skips the download. To change FFmpeg, change the extracted ffmpeg-7.1/ folder before you run the script.

How to replace the framework in the app

  1. Build your FFmpeg.framework as above, from FFmpeg 7.1 and with the same ABI: the same library versions as in the framework's Headers folder, the install name @rpath/FFmpeg.framework/FFmpeg, and a minimum tvOS of 18.0.
  2. Replace Astrape.app/Frameworks/FFmpeg.framework with your framework.
  3. Re-sign the framework, then the app, with your own signing identity, because the app's signature covers the framework:
    codesign --force --sign "<your identity>" Astrape.app/Frameworks/FFmpeg.framework
    codesign --force --sign "<your identity>" --preserve-metadata=entitlements Astrape.app
  4. Install the re-signed app on your Apple TV with your own provisioning.

Written offer

For FFmpeg and dav1d as built into FFmpeg.framework, we will give you the object files of those two libraries on request (the .o files of the static FFmpeg and dav1d libraries that the framework is linked from), for at least three years from the release of the Astrape version that contains this framework. The source, the build script and the licence texts are already on this page.

To ask, write to [email protected], and say which Astrape version you have (Settings, About). The licence texts of everything else in the app are in the app, under Acknowledgements.