first commit
Some checks failed
/ buid (push) Has been cancelled

This commit is contained in:
2026-04-16 14:48:09 +07:00
commit 4b968a3347
5625 changed files with 1685474 additions and 0 deletions

View File

@ -0,0 +1,448 @@
//
// BuildFFMPEG.swift
//
//
// Created by kintan on 12/26/23.
//
import Foundation
class BuildFFMPEG: BaseBuild {
init() {
super.init(library: .FFmpeg)
if Utility.shell("which nasm") == nil {
Utility.shell("brew install nasm")
}
if Utility.shell("which sdl2-config") == nil {
Utility.shell("brew install sdl2")
}
let lldbFile = URL.currentDirectory + "LLDBInitFile"
try? FileManager.default.removeItem(at: lldbFile)
FileManager.default.createFile(atPath: lldbFile.path, contents: nil, attributes: nil)
let path = directoryURL + "libavcodec/videotoolbox.c"
if let data = FileManager.default.contents(atPath: path.path), var str = String(data: data, encoding: .utf8) {
str = str.replacingOccurrences(of: "kCVPixelBufferOpenGLESCompatibilityKey", with: "kCVPixelBufferMetalCompatibilityKey")
str = str.replacingOccurrences(of: "kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey", with: "kCVPixelBufferMetalCompatibilityKey")
try! str.write(toFile: path.path, atomically: true, encoding: .utf8)
}
}
override func flagsDependencelibrarys() -> [Library] {
[.gmp, .nettle, .gnutls, .libsmbclient]
}
override func frameworks() throws -> [String] {
var frameworks: [String] = []
if let platform = platforms().first {
if let arch = platform.architectures.first {
let lib = thinDir(platform: platform, arch: arch) + "lib"
let fileNames = try FileManager.default.contentsOfDirectory(atPath: lib.path)
for fileName in fileNames {
if fileName.hasPrefix("lib"), fileName.hasSuffix(".a") {
// libavformat,lib
frameworks.append("Lib" + fileName.dropFirst(3).dropLast(2))
}
}
}
}
return frameworks
}
override func ldFlags(platform: PlatformType, arch: ArchType) -> [String] {
var ldFlags = super.ldFlags(platform: platform, arch: arch)
ldFlags.append("-lc++")
return ldFlags
}
override func environment(platform: PlatformType, arch: ArchType) -> [String: String] {
var env = super.environment(platform: platform, arch: arch)
env["CPPFLAGS"] = env["CFLAGS"]
return env
}
override func build(platform: PlatformType, arch: ArchType, buildURL: URL) throws {
try super.build(platform: platform, arch: arch, buildURL: buildURL)
let prefix = thinDir(platform: platform, arch: arch)
let lldbFile = URL.currentDirectory + "LLDBInitFile"
if let data = FileManager.default.contents(atPath: lldbFile.path), var str = String(data: data, encoding: .utf8) {
str.append("settings \(str.isEmpty ? "set" : "append") target.source-map \((buildURL + "src").path) \(directoryURL.path)\n")
try str.write(toFile: lldbFile.path, atomically: true, encoding: .utf8)
}
try FileManager.default.copyItem(at: buildURL + "config.h", to: prefix + "include/libavutil/config.h")
try FileManager.default.copyItem(at: buildURL + "config.h", to: prefix + "include/libavcodec/config.h")
try FileManager.default.copyItem(at: buildURL + "config.h", to: prefix + "include/libavformat/config.h")
try FileManager.default.copyItem(at: buildURL + "src/libavutil/getenv_utf8.h", to: prefix + "include/libavutil/getenv_utf8.h")
try FileManager.default.copyItem(at: buildURL + "src/libavutil/libm.h", to: prefix + "include/libavutil/libm.h")
try FileManager.default.copyItem(at: buildURL + "src/libavutil/thread.h", to: prefix + "include/libavutil/thread.h")
try FileManager.default.copyItem(at: buildURL + "src/libavutil/intmath.h", to: prefix + "include/libavutil/intmath.h")
try FileManager.default.copyItem(at: buildURL + "src/libavutil/mem_internal.h", to: prefix + "include/libavutil/mem_internal.h")
try FileManager.default.copyItem(at: buildURL + "src/libavutil/attributes_internal.h", to: prefix + "include/libavutil/attributes_internal.h")
try FileManager.default.copyItem(at: buildURL + "src/libavcodec/mathops.h", to: prefix + "include/libavcodec/mathops.h")
try FileManager.default.copyItem(at: buildURL + "src/libavformat/os_support.h", to: prefix + "include/libavformat/os_support.h")
let internalPath = prefix + "include/libavutil/internal.h"
try FileManager.default.copyItem(at: buildURL + "src/libavutil/internal.h", to: internalPath)
if let data = FileManager.default.contents(atPath: internalPath.path), var str = String(data: data, encoding: .utf8) {
str = str.replacingOccurrences(of: """
#include "timer.h"
""", with: """
// #include "timer.h"
""")
str = str.replacingOccurrences(of: "kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey", with: "kCVPixelBufferMetalCompatibilityKey")
try str.write(toFile: internalPath.path, atomically: true, encoding: .utf8)
}
if platform == .macos, arch.executable {
let fftoolsFile = URL.currentDirectory + "../Sources/fftools"
try? FileManager.default.removeItem(at: fftoolsFile)
if !FileManager.default.fileExists(atPath: (fftoolsFile + "include/compat").path) {
try FileManager.default.createDirectory(at: fftoolsFile + "include/compat", withIntermediateDirectories: true)
}
try FileManager.default.copyItem(at: buildURL + "src/compat/va_copy.h", to: fftoolsFile + "include/compat/va_copy.h")
try FileManager.default.copyItem(at: buildURL + "config.h", to: fftoolsFile + "include/config.h")
try FileManager.default.copyItem(at: buildURL + "config_components.h", to: fftoolsFile + "include/config_components.h")
if !FileManager.default.fileExists(atPath: (fftoolsFile + "include/libavdevice").path) {
try FileManager.default.createDirectory(at: fftoolsFile + "include/libavdevice", withIntermediateDirectories: true)
}
try FileManager.default.copyItem(at: buildURL + "src/libavdevice/avdevice.h", to: fftoolsFile + "include/libavdevice/avdevice.h")
try FileManager.default.copyItem(at: buildURL + "src/libavdevice/version_major.h", to: fftoolsFile + "include/libavdevice/version_major.h")
try FileManager.default.copyItem(at: buildURL + "src/libavdevice/version.h", to: fftoolsFile + "include/libavdevice/version.h")
if !FileManager.default.fileExists(atPath: (fftoolsFile + "include/libpostproc").path) {
try FileManager.default.createDirectory(at: fftoolsFile + "include/libpostproc", withIntermediateDirectories: true)
}
try FileManager.default.copyItem(at: buildURL + "src/libpostproc/postprocess_internal.h", to: fftoolsFile + "include/libpostproc/postprocess_internal.h")
try FileManager.default.copyItem(at: buildURL + "src/libpostproc/postprocess.h", to: fftoolsFile + "include/libpostproc/postprocess.h")
try FileManager.default.copyItem(at: buildURL + "src/libpostproc/version_major.h", to: fftoolsFile + "include/libpostproc/version_major.h")
try FileManager.default.copyItem(at: buildURL + "src/libpostproc/version.h", to: fftoolsFile + "include/libpostproc/version.h")
let ffplayFile = URL.currentDirectory + "../Sources/ffplay"
try? FileManager.default.removeItem(at: ffplayFile)
try FileManager.default.createDirectory(at: ffplayFile, withIntermediateDirectories: true)
let ffprobeFile = URL.currentDirectory + "../Sources/ffprobe"
try? FileManager.default.removeItem(at: ffprobeFile)
try FileManager.default.createDirectory(at: ffprobeFile, withIntermediateDirectories: true)
let ffmpegFile = URL.currentDirectory + "../Sources/ffmpeg"
try? FileManager.default.removeItem(at: ffmpegFile)
try FileManager.default.createDirectory(at: ffmpegFile + "include", withIntermediateDirectories: true)
let fftools = buildURL + "src/fftools"
let fileNames = try FileManager.default.contentsOfDirectory(atPath: fftools.path)
for fileName in fileNames {
if fileName.hasPrefix("ffplay") {
try FileManager.default.copyItem(at: fftools + fileName, to: ffplayFile + fileName)
} else if fileName.hasPrefix("ffprobe") {
try FileManager.default.copyItem(at: fftools + fileName, to: ffprobeFile + fileName)
} else if fileName.hasPrefix("ffmpeg") {
if fileName.hasSuffix(".h") {
try FileManager.default.copyItem(at: fftools + fileName, to: ffmpegFile + "include" + fileName)
} else {
try FileManager.default.copyItem(at: fftools + fileName, to: ffmpegFile + fileName)
}
} else if fileName.hasSuffix(".h") {
try FileManager.default.copyItem(at: fftools + fileName, to: fftoolsFile + "include" + fileName)
} else if fileName.hasSuffix(".c") {
try FileManager.default.copyItem(at: fftools + fileName, to: fftoolsFile + fileName)
}
}
let prefix = scratch(platform: platform, arch: arch)
try? FileManager.default.removeItem(at: URL(fileURLWithPath: "/usr/local/bin/ffmpeg"))
try? FileManager.default.copyItem(at: prefix + "ffmpeg", to: URL(fileURLWithPath: "/usr/local/bin/ffmpeg"))
try? FileManager.default.removeItem(at: URL(fileURLWithPath: "/usr/local/bin/ffplay"))
try? FileManager.default.copyItem(at: prefix + "ffplay", to: URL(fileURLWithPath: "/usr/local/bin/ffplay"))
try? FileManager.default.removeItem(at: URL(fileURLWithPath: "/usr/local/bin/ffprobe"))
try? FileManager.default.copyItem(at: prefix + "ffprobe", to: URL(fileURLWithPath: "/usr/local/bin/ffprobe"))
}
}
override func frameworkExcludeHeaders(_ framework: String) -> [String] {
if framework == "Libavcodec" {
return ["xvmc", "vdpau", "qsv", "dxva2", "d3d11va", "mathops", "videotoolbox"]
} else if framework == "Libavutil" {
return ["hwcontext_vulkan", "hwcontext_vdpau", "hwcontext_vaapi", "hwcontext_qsv", "hwcontext_opencl", "hwcontext_dxva2", "hwcontext_d3d11va", "hwcontext_cuda", "hwcontext_videotoolbox", "getenv_utf8", "intmath", "libm", "thread", "mem_internal", "internal", "attributes_internal"]
} else if framework == "Libavformat" {
return ["os_support"]
} else {
return super.frameworkExcludeHeaders(framework)
}
}
override func arguments(platform: PlatformType, arch: ArchType) -> [String] {
var arguments = [
"--prefix=\(thinDir(platform: platform, arch: arch).path)",
]
arguments += ffmpegConfiguers
arguments += Build.ffmpegConfiguers
arguments.append("--arch=\(arch.cpuFamily)")
if platform == .android {
arguments.append("--target-os=android")
// appleandroid
arguments.append("--cc=\(platform.cc)")
arguments.append("--cxx=\(platform.cc)++")
// arguments.append("--cross-prefix=\(platform.host(arch: arch))-")
// arguments.append("--sysroot=\(platform.isysroot)")
} else {
arguments.append("--target-os=darwin")
arguments.append("--enable-libxml2")
}
// arguments.append(arch.cpu())
/**
aacpsdsp.o), building for Mac Catalyst, but linking in object file built for
x86_64 binaries are built without ASM support, since ASM for x86_64 is actually x86 and that confuses `xcodebuild -create-xcframework` https://stackoverflow.com/questions/58796267/building-for-macos-but-linking-in-object-file-built-for-free-standing/59103419#59103419
*/
if platform == .maccatalyst || arch == .x86_64 {
arguments.append("--disable-neon")
arguments.append("--disable-asm")
} else {
arguments.append("--enable-neon")
arguments.append("--enable-asm")
}
if ![.watchsimulator, .watchos, .android].contains(platform) {
arguments.append("--enable-videotoolbox")
arguments.append("--enable-audiotoolbox")
arguments.append("--enable-filter=yadif_videotoolbox")
arguments.append("--enable-filter=scale_vt")
arguments.append("--enable-filter=transpose_vt")
} else {
arguments.append("--enable-encoder=h264_videotoolbox")
arguments.append("--enable-encoder=hevc_videotoolbox")
arguments.append("--enable-encoder=prores_videotoolbox")
}
if platform == .macos, arch.executable {
arguments.append("--enable-ffplay")
arguments.append("--enable-sdl2")
arguments.append("--enable-decoder=rawvideo")
arguments.append("--enable-filter=color")
arguments.append("--enable-filter=lut")
arguments.append("--enable-filter=testsrc")
// debug
arguments.append("--enable-debug")
arguments.append("--enable-debug=3")
arguments.append("--disable-stripping")
} else {
arguments.append("--disable-programs")
}
if platform == .macos {
arguments.append("--enable-outdev=audiotoolbox")
}
if !([PlatformType.tvos, .tvsimulator, .xros, .xrsimulator].contains(platform)) {
// tvos17AVCaptureDeviceInput
// 'defaultDeviceWithMediaType:' is unavailable: not available on visionOS
arguments.append("--enable-indev=avfoundation")
}
// if platform == .isimulator || platform == .tvsimulator {
// arguments.append("--assert-level=1")
// }
for library in Library.allCases {
let path = URL.currentDirectory + [library.rawValue, platform.rawValue, "thin", arch.rawValue]
if FileManager.default.fileExists(atPath: path.path), library.isFFmpegDependentLibrary {
arguments.append("--enable-\(library.rawValue)")
if library == .libsrt || library == .libsmbclient {
arguments.append("--enable-protocol=\(library.rawValue)")
} else if library == .libdav1d {
arguments.append("--enable-decoder=\(library.rawValue)")
} else if library == .libass {
arguments.append("--enable-filter=ass")
arguments.append("--enable-filter=subtitles")
} else if library == .libzvbi {
arguments.append("--enable-decoder=libzvbi_teletext")
} else if library == .libplacebo {
arguments.append("--enable-filter=libplacebo")
}
}
}
return arguments
}
/*
boxblur_filter_deps="gpl"
delogo_filter_deps="gpl"
*/
private let ffmpegConfiguers = [
// Configuration options:
"--disable-armv5te", "--disable-armv6", "--disable-armv6t2",
"--disable-bzlib", "--disable-gray", "--disable-iconv", "--disable-linux-perf",
"--disable-shared", "--disable-small", "--disable-swscale-alpha", "--disable-symver", "--disable-xlib",
"--enable-cross-compile",
"--enable-optimizations", "--enable-pic", "--enable-runtime-cpudetect", "--enable-static", "--enable-thumb", "--enable-version3",
"--pkg-config-flags=--static",
// Documentation options:
"--disable-doc", "--disable-htmlpages", "--disable-manpages", "--disable-podpages", "--disable-txtpages",
// Component options:
"--enable-avcodec", "--enable-avformat", "--enable-avutil", "--enable-network", "--enable-swresample", "--enable-swscale",
"--disable-devices", "--disable-outdevs", "--disable-indevs", "--disable-postproc",
"--enable-indev=lavfi",
// ,"--disable-pthreads"
// ,"--disable-w32threads"
// ,"--disable-os2threads"
// ,"--disable-dct"
// ,"--disable-dwt"
// ,"--disable-lsp"
// ,"--disable-lzo"
// ,"--disable-mdct"
// ,"--disable-rdft"
// ,"--disable-fft"
// Hardware accelerators:
"--disable-d3d11va", "--disable-dxva2", "--disable-vaapi", "--disable-vdpau",
// todo ffmpeglibavcodec/vulkan_video_codec_av1std.h
"--disable-hwaccel=av1_vulkan,hevc_vulkan,h264_vulkan",
// Individual component options:
// ,"--disable-everything"
// ./configure --list-muxers
"--disable-muxers",
"--enable-muxer=flac", "--enable-muxer=dash", "--enable-muxer=hevc",
"--enable-muxer=m4v", "--enable-muxer=matroska", "--enable-muxer=mov", "--enable-muxer=mp4",
"--enable-muxer=mpegts", "--enable-muxer=webm*",
"--enable-muxer=nut",
// ./configure --list-encoders
"--disable-encoders",
"--enable-encoder=aac", "--enable-encoder=alac", "--enable-encoder=flac", "--enable-encoder=pcm*",
"--enable-encoder=movtext", "--enable-encoder=mpeg4", "--enable-encoder=prores",
// ./configure --list-protocols
"--enable-protocols",
// ./configure --list-demuxers
// demuxersavformat8MB4MB
"--disable-demuxers",
"--enable-demuxer=aac", "--enable-demuxer=ac3", "--enable-demuxer=aiff", "--enable-demuxer=amr",
"--enable-demuxer=ape", "--enable-demuxer=asf", "--enable-demuxer=ass", "--enable-demuxer=av1",
"--enable-demuxer=avi", "--enable-demuxer=caf", "--enable-demuxer=concat",
"--enable-demuxer=dash", "--enable-demuxer=data", "--enable-demuxer=dv",
"--enable-demuxer=eac3",
"--enable-demuxer=flac", "--enable-demuxer=flv", "--enable-demuxer=h264", "--enable-demuxer=hevc",
"--enable-demuxer=hls", "--enable-demuxer=live_flv", "--enable-demuxer=loas", "--enable-demuxer=m4v",
// matroska=mkv,mka,mks,mk3d
"--enable-demuxer=matroska", "--enable-demuxer=mov", "--enable-demuxer=mp3", "--enable-demuxer=mpeg*",
"--enable-demuxer=nut",
"--enable-demuxer=ogg", "--enable-demuxer=rm", "--enable-demuxer=rtsp", "--enable-demuxer=rtp", "--enable-demuxer=srt",
"--enable-demuxer=vc1", "--enable-demuxer=wav", "--enable-demuxer=webm_dash_manifest",
// ./configure --list-bsfs
"--enable-bsfs",
// ./configure --list-decoders
// decodersavcodec40MB20MB
"--disable-decoders",
//
"--enable-decoder=av1", "--enable-decoder=dca", "--enable-decoder=dxv",
"--enable-decoder=ffv1", "--enable-decoder=ffvhuff", "--enable-decoder=flv",
"--enable-decoder=h263", "--enable-decoder=h263i", "--enable-decoder=h263p", "--enable-decoder=h264",
"--enable-decoder=hap", "--enable-decoder=hevc", "--enable-decoder=huffyuv",
"--enable-decoder=indeo5",
"--enable-decoder=mjpeg", "--enable-decoder=mjpegb", "--enable-decoder=mpeg*", "--enable-decoder=mts2",
"--enable-decoder=prores",
"--enable-decoder=rv10", "--enable-decoder=rv20", "--enable-decoder=rv30", "--enable-decoder=rv40",
"--enable-decoder=snow", "--enable-decoder=svq3",
"--enable-decoder=tscc", "--enable-decoder=tscc2", "--enable-decoder=txd",
"--enable-decoder=wmv1", "--enable-decoder=wmv2", "--enable-decoder=wmv3",
"--enable-decoder=vc1", "--enable-decoder=vp6", "--enable-decoder=vp6a", "--enable-decoder=vp6f",
"--enable-decoder=vp7", "--enable-decoder=vp8", "--enable-decoder=vp9",
//
"--enable-decoder=aac*", "--enable-decoder=ac3*", "--enable-decoder=adpcm*", "--enable-decoder=alac*",
"--enable-decoder=amr*", "--enable-decoder=ape", "--enable-decoder=cook",
"--enable-decoder=dca", "--enable-decoder=dolby_e", "--enable-decoder=eac3*", "--enable-decoder=flac",
"--enable-decoder=mp1*", "--enable-decoder=mp2*", "--enable-decoder=mp3*", "--enable-decoder=opus",
"--enable-decoder=pcm*", "--enable-decoder=sonic",
"--enable-decoder=truehd", "--enable-decoder=tta", "--enable-decoder=vorbis", "--enable-decoder=wma*", "--enable-decoder=wrapped_avframe",
//
"--enable-decoder=ass", "--enable-decoder=ccaption", "--enable-decoder=dvbsub", "--enable-decoder=dvdsub",
"--enable-decoder=mpl2", "--enable-decoder=movtext",
"--enable-decoder=pgssub", "--enable-decoder=srt", "--enable-decoder=ssa", "--enable-decoder=subrip",
"--enable-decoder=xsub", "--enable-decoder=webvtt",
// ./configure --list-filters
"--disable-filters",
"--enable-filter=aformat", "--enable-filter=amix", "--enable-filter=anull", "--enable-filter=aresample",
"--enable-filter=areverse", "--enable-filter=asetrate", "--enable-filter=atempo", "--enable-filter=atrim",
"--enable-filter=boxblur", "--enable-filter=bwdif", "--enable-filter=delogo",
"--enable-filter=equalizer", "--enable-filter=estdif",
"--enable-filter=firequalizer", "--enable-filter=format", "--enable-filter=fps",
"--enable-filter=gblur",
"--enable-filter=hflip", "--enable-filter=hwdownload", "--enable-filter=hwmap", "--enable-filter=hwupload",
"--enable-filter=idet", "--enable-filter=lenscorrection", "--enable-filter=lut*", "--enable-filter=negate", "--enable-filter=null",
"--enable-filter=overlay",
"--enable-filter=palettegen", "--enable-filter=paletteuse", "--enable-filter=pan",
"--enable-filter=rotate",
"--enable-filter=scale", "--enable-filter=setpts", "--enable-filter=superequalizer",
"--enable-filter=transpose", "--enable-filter=trim",
"--enable-filter=vflip", "--enable-filter=volume",
"--enable-filter=w3fdif",
"--enable-filter=yadif",
"--enable-filter=avgblur_vulkan", "--enable-filter=blend_vulkan", "--enable-filter=bwdif_vulkan",
"--enable-filter=chromaber_vulkan", "--enable-filter=flip_vulkan", "--enable-filter=gblur_vulkan",
"--enable-filter=hflip_vulkan", "--enable-filter=nlmeans_vulkan", "--enable-filter=overlay_vulkan",
"--enable-filter=vflip_vulkan", "--enable-filter=xfade_vulkan",
]
}
class BuildZvbi: BaseBuild {
init() {
super.init(library: .libzvbi)
let path = directoryURL + "configure.ac"
if let data = FileManager.default.contents(atPath: path.path), var str = String(data: data, encoding: .utf8) {
str = str.replacingOccurrences(of: "AC_FUNC_MALLOC", with: "")
str = str.replacingOccurrences(of: "AC_FUNC_REALLOC", with: "")
try! str.write(toFile: path.path, atomically: true, encoding: .utf8)
}
}
override func platforms() -> [PlatformType] {
super.platforms().filter {
$0 != .maccatalyst
}
}
override func arguments(platform: PlatformType, arch: ArchType) -> [String] {
["--host=\(platform.host(arch: arch))",
"--prefix=\(thinDir(platform: platform, arch: arch).path)"]
}
}
class BuildSRT: BaseBuild {
init() {
super.init(library: .libsrt)
}
override func arguments(platform: PlatformType, arch _: ArchType) -> [String] {
[
"-Wno-dev",
// "-DUSE_ENCLIB=openssl",
"-DUSE_ENCLIB=gnutls",
"-DENABLE_STDCXX_SYNC=1",
"-DENABLE_CXX11=1",
"-DUSE_OPENSSL_PC=1",
"-DENABLE_DEBUG=0",
"-DENABLE_LOGGING=0",
"-DENABLE_HEAVY_LOGGING=0",
"-DENABLE_APPS=0",
"-DENABLE_SHARED=0",
platform == .maccatalyst ? "-DENABLE_MONOTONIC_CLOCK=0" : "-DENABLE_MONOTONIC_CLOCK=1",
]
}
}
class BuildFontconfig: BaseBuild {
init() {
super.init(library: .libfontconfig)
}
override func arguments(platform _: PlatformType, arch _: ArchType) -> [String] {
[
"-Ddoc=disabled",
"-Dtests=disabled",
]
}
}
class BuildBluray: BaseBuild {
init() {
super.init(library: .libbluray)
}
// macosmount
override func platforms() -> [PlatformType] {
[.macos]
}
override func arguments(platform: PlatformType, arch: ArchType) -> [String] {
[
"--disable-bdjava-jar",
"--disable-silent-rules",
"--disable-dependency-tracking",
"--host=\(platform.host(arch: arch))",
"--prefix=\(thinDir(platform: platform, arch: arch).path)",
]
}
}