mirror of
https://github.com/MyLuxy/overdrive.git
synced 2026-10-17 18:02:48 +02:00
97 lines
5.2 KiB
Python
97 lines
5.2 KiB
Python
# Copyright (C) 2026 half144 and PS5 React contributors
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
# Additional attribution term: see LICENSE-ATTRIBUTION.
|
|
"""The pinned FFmpeg release (LGPL-3.0-or-later as configured), built static for each host.
|
|
|
|
Both hosts build the same source with the same components, so the preview decodes what the PS5 does.
|
|
The lock's patches (backported upstream fixes) are applied in order to the extracted release. A
|
|
build is reused while its configure line and patches are unchanged."""
|
|
import hashlib
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import tarfile
|
|
|
|
from common import DEPS, LOCK, ROOT, fetch, run
|
|
|
|
COMPONENTS = [
|
|
"--disable-everything", "--disable-autodetect", "--disable-programs", "--disable-doc", "--disable-debug",
|
|
"--disable-avdevice", "--disable-avfilter", "--disable-postproc",
|
|
"--enable-avcodec", "--enable-avformat", "--enable-avutil", "--enable-swresample", "--enable-swscale",
|
|
"--enable-network", "--enable-pthreads", "--enable-version3",
|
|
"--enable-demuxer=mov,matroska,mpegts,mpegps,hls,avi,flv,flac,mp3,aac,ac3,eac3,dts,truehd,ogg,wav,ivf,webvtt,srt,ass",
|
|
"--enable-protocol=file,pipe,http,tcp,crypto,https,tls",
|
|
"--enable-decoder=h264,hevc,vp8,vp9,mpeg4,mpeg2video,mpeg1video,msmpeg4v3,vc1,mjpeg",
|
|
"--enable-decoder=aac,aac_latm,ac3,eac3,mp3,mp2,opus,vorbis,flac,alac,truehd,mlp,dca",
|
|
"--enable-decoder=pcm_s16le,pcm_s16be,pcm_s24le,pcm_s24be,pcm_s32le,pcm_f32le,pcm_u8,pcm_bluray,pcm_dvd",
|
|
"--enable-decoder=subrip,ass,ssa,movtext,webvtt",
|
|
"--enable-parser=h264,hevc,vp8,vp9,av1,mpeg4video,mpegvideo,vc1,mjpeg,aac,aac_latm,ac3,mpegaudio,opus,vorbis,flac,mlp,dca",
|
|
"--enable-bsf=h264_mp4toannexb,hevc_mp4toannexb,extract_extradata,aac_adtstoasc,vp9_superframe_split",
|
|
]
|
|
LIBRARIES = ["libavformat.a", "libavcodec.a", "libswscale.a", "libswresample.a", "libavutil.a"]
|
|
|
|
|
|
def patches_digest():
|
|
"""What the lock's patches say, so a source tree or build with other patches is redone."""
|
|
digest = hashlib.sha256()
|
|
for patch in LOCK["ffmpeg"].get("patches", ()):
|
|
digest.update(patch.encode() + b"\0" + (ROOT / patch).read_bytes())
|
|
return digest.hexdigest() if LOCK["ffmpeg"].get("patches") else ""
|
|
|
|
|
|
def source():
|
|
"""Source directory of the pinned release with the lock's patches applied."""
|
|
pinned = LOCK["ffmpeg"]
|
|
directory = DEPS / f"ffmpeg-{pinned['version']}"
|
|
marker = directory / ".ps5-react-patches"
|
|
applied = marker.read_text() if marker.exists() else ""
|
|
if (directory / "configure").exists() and applied != patches_digest():
|
|
shutil.rmtree(directory)
|
|
if not (directory / "configure").exists():
|
|
archive = fetch(pinned["url"], DEPS / f"ffmpeg-{pinned['version']}.tar.xz", pinned["sha256"])
|
|
with tarfile.open(archive) as package:
|
|
package.extractall(DEPS, filter="data")
|
|
for patch in pinned.get("patches", ()):
|
|
run(["git", "apply", "--whitespace=nowarn", ROOT / patch], cwd=directory)
|
|
marker.write_text(patches_digest())
|
|
return directory
|
|
|
|
|
|
def _build(name, arguments, env=None):
|
|
"""Configures and builds into .deps/ffmpeg-<version>-<name>; returns the install prefix."""
|
|
src = source()
|
|
root = DEPS / f"{src.name}-{name}"
|
|
prefix, build = root / "prefix", root / "build"
|
|
stamp = hashlib.sha256("\n".join([*arguments, patches_digest()]).encode()).hexdigest()
|
|
if (root / "stamp").exists() and (root / "stamp").read_text() == stamp and \
|
|
all((prefix / "lib" / library).exists() for library in LIBRARIES):
|
|
return prefix
|
|
shutil.rmtree(root, ignore_errors=True)
|
|
build.mkdir(parents=True)
|
|
run([src / "configure", f"--prefix={prefix}", *arguments], env=env, cwd=build, log=root / "configure.log")
|
|
run(["make", f"-j{os.cpu_count() or 4}"], env=env, cwd=build, log=root / "make.log")
|
|
run(["make", "install"], env=env, cwd=build, log=root / "install.log")
|
|
(root / "stamp").write_text(stamp)
|
|
return prefix
|
|
|
|
|
|
def desktop():
|
|
"""macOS: TLS through SecureTransport, h264/hevc through VideoToolbox when the decoder asks."""
|
|
return _build("desktop", ["--cc=clang", "--enable-static", "--disable-shared", "--pkg-config=false",
|
|
*COMPONENTS, "--enable-securetransport", "--enable-videotoolbox",
|
|
"--enable-hwaccel=h264_videotoolbox,hevc_videotoolbox"])
|
|
|
|
|
|
def ps5(sdk, network_ports, env):
|
|
"""The PS5: the payload SDK's compiler as a FreeBSD x86-64 cross build, TLS from the pinned OpenSSL."""
|
|
if not shutil.which("nasm"):
|
|
raise RuntimeError("FFmpeg's x86 assembly needs nasm: brew install nasm")
|
|
bin = Path(sdk) / "bin"
|
|
return _build("ps5", [
|
|
"--enable-cross-compile", "--arch=x86_64", "--cpu=znver2", "--target-os=freebsd",
|
|
f"--cc={bin / 'prospero-clang'}", f"--cxx={bin / 'prospero-clang++'}", f"--ar={bin / 'prospero-ar'}",
|
|
f"--nm={bin / 'prospero-nm'}", f"--ranlib={bin / 'prospero-ranlib'}", f"--strip={bin / 'prospero-strip'}",
|
|
"--pkg-config=false", "--x86asmexe=nasm", "--enable-static", "--disable-shared", "--enable-pic",
|
|
"--enable-openssl", f"--extra-cflags=-I{Path(network_ports) / 'include'}",
|
|
f"--extra-ldflags=-L{Path(network_ports) / 'lib'}", *COMPONENTS], env=env)
|