summaryrefslogtreecommitdiffstats
path: root/TOOLS
diff options
context:
space:
mode:
Diffstat (limited to 'TOOLS')
-rw-r--r--TOOLS/__init__.py0
-rwxr-xr-xTOOLS/appveyor-build.sh24
-rwxr-xr-xTOOLS/appveyor-install.sh72
-rwxr-xr-xTOOLS/docutils-wrapper.py67
-rwxr-xr-xTOOLS/dylib-unhell.py130
-rwxr-xr-xTOOLS/dylib_unhell.py268
-rwxr-xr-xTOOLS/file2string.py16
-rwxr-xr-xTOOLS/gen-interface-changes.py83
-rwxr-xr-xTOOLS/idet.sh2
-rw-r--r--TOOLS/lua/acompressor.lua2
-rw-r--r--TOOLS/lua/autocrop.lua246
-rw-r--r--TOOLS/lua/autodeint.lua2
-rw-r--r--TOOLS/lua/autoload.lua280
-rw-r--r--TOOLS/lua/command-test.lua19
-rw-r--r--TOOLS/lua/skip-logo.lua2
-rwxr-xr-xTOOLS/macos-sdk-version.py46
-rwxr-xr-xTOOLS/macos-swift-lib-directory.py42
-rwxr-xr-xTOOLS/matroska.py16
-rwxr-xr-xTOOLS/mpv_identify.sh2
-rwxr-xr-xTOOLS/osxbundle.py49
-rw-r--r--TOOLS/osxbundle/meson.build8
-rw-r--r--TOOLS/osxbundle/mpv.app/Contents/Info.plist13
-rwxr-xr-xTOOLS/travis-deps139
-rwxr-xr-xTOOLS/travis-rebuild-website29
-rwxr-xr-xTOOLS/umpv9
25 files changed, 904 insertions, 662 deletions
diff --git a/TOOLS/__init__.py b/TOOLS/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/TOOLS/__init__.py
+++ /dev/null
diff --git a/TOOLS/appveyor-build.sh b/TOOLS/appveyor-build.sh
deleted file mode 100755
index a6a7b724a3..0000000000
--- a/TOOLS/appveyor-build.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/bash
-set -e
-
-export DEST_OS=win32
-export CC=gcc
-export PKG_CONFIG=/usr/bin/pkg-config
-export PERL=/usr/bin/perl
-export PYTHON=/usr/bin/python3
-
-"$PYTHON" bootstrap.py
-"$PYTHON" waf configure \
- --check-c-compiler=gcc \
- --enable-spirv-cross \
- --enable-d3d-hwaccel \
- --enable-d3d11 \
- --enable-jpeg \
- --enable-lcms2 \
- --enable-libarchive \
- --enable-lua \
- --enable-rubberband \
- --enable-shaderc \
- --enable-uchardet \
- --enable-vulkan
-"$PYTHON" waf build
diff --git a/TOOLS/appveyor-install.sh b/TOOLS/appveyor-install.sh
deleted file mode 100755
index 7b2473f39d..0000000000
--- a/TOOLS/appveyor-install.sh
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/bash
-set -e
-
-export PYTHON=/usr/bin/python3
-
-# Write an empty fonts.conf to speed up fc-cache
-export FONTCONFIG_FILE=/dummy-fonts.conf
-cat >"$FONTCONFIG_FILE" <<EOF
-<?xml version="1.0"?>
-<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
-<fontconfig></fontconfig>
-EOF
-
-# Install build dependencies for mpv
-pacman -S --noconfirm --needed \
- $MINGW_PACKAGE_PREFIX-toolchain \
- $MINGW_PACKAGE_PREFIX-cmake \
- $MINGW_PACKAGE_PREFIX-lcms2 \
- $MINGW_PACKAGE_PREFIX-libarchive \
- $MINGW_PACKAGE_PREFIX-libass \
- $MINGW_PACKAGE_PREFIX-libjpeg-turbo \
- $MINGW_PACKAGE_PREFIX-libplacebo \
- $MINGW_PACKAGE_PREFIX-lua51 \
- $MINGW_PACKAGE_PREFIX-ninja \
- $MINGW_PACKAGE_PREFIX-rubberband \
- $MINGW_PACKAGE_PREFIX-uchardet \
- $MINGW_PACKAGE_PREFIX-vulkan
-
-# Delete unused packages to reduce space used in the Appveyor cache
-pacman -Sc --noconfirm
-
-# Compile ffmpeg
-(
- git clone --depth=1 https://github.com/FFmpeg/ffmpeg.git && cd ffmpeg
-
- mkdir build && cd build
- ../configure \
- --prefix=$MINGW_PREFIX \
- --target-os=mingw32 \
- --arch=$MSYSTEM_CARCH \
- --disable-static \
- --disable-doc \
- --disable-asm \
- --enable-gpl \
- --enable-version3 \
- --enable-shared \
- --enable-pic \
- --enable-d3d11va \
- --enable-dxva2 \
- --enable-schannel
- make -j4 install
-)
-
-# Compile shaderc
-(
- git clone --depth=1 https://github.com/google/shaderc && cd shaderc
- "$PYTHON" utils/git-sync-deps
-
- mkdir build && cd build
- cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DSHADERC_SKIP_TESTS=ON \
- -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX ..
- ninja install
-)
-
-# Compile SPIRV-Cross
-(
- git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Cross && cd SPIRV-Cross
-
- mkdir build && cd build
- cmake -GNinja -DSPIRV_CROSS_SHARED=ON -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX ..
- ninja install
-)
diff --git a/TOOLS/docutils-wrapper.py b/TOOLS/docutils-wrapper.py
new file mode 100755
index 0000000000..31ba976e64
--- /dev/null
+++ b/TOOLS/docutils-wrapper.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+"""
+Wrapper around docutils rst2x commands,
+converting their dependency files to a format understood by meson/ninja.
+"""
+
+#
+# This file is part of mpv.
+#
+# mpv is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# mpv is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with mpv. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import subprocess
+import sys
+
+
+def convert_depfile(output, depfile):
+ with open(depfile, 'r') as f:
+ deps = f.readlines()
+
+ with open(depfile, 'w') as f:
+ f.write(os.path.abspath(output))
+ f.write(': \\\n')
+ for dep in deps:
+ dep = dep[:-1]
+ f.write('\t')
+ f.write(os.path.abspath(dep))
+ f.write(' \\\n')
+
+def remove(path):
+ try:
+ os.remove(path)
+ except FileNotFoundError:
+ pass
+
+argv = sys.argv[1:]
+
+depfile = None
+output = argv[-1]
+
+for opt, optarg in zip(argv, argv[1:]):
+ if opt == '--record-dependencies':
+ depfile = optarg
+
+try:
+ proc = subprocess.run(argv, check=True)
+ if depfile is not None:
+ convert_depfile(output, depfile)
+except:
+ remove(output)
+ if depfile is not None:
+ remove(depfile)
+ sys.exit(1)
+
+sys.exit(proc.returncode)
diff --git a/TOOLS/dylib-unhell.py b/TOOLS/dylib-unhell.py
deleted file mode 100755
index 19ef4118fa..0000000000
--- a/TOOLS/dylib-unhell.py
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/usr/bin/env python
-
-import re
-import os
-import sys
-import shutil
-import subprocess
-from functools import partial
-
-sys_re = re.compile("^/System")
-usr_re = re.compile("^/usr/lib/")
-exe_re = re.compile("@executable_path")
-
-def is_user_lib(objfile, libname):
- return not sys_re.match(libname) and \
- not usr_re.match(libname) and \
- not exe_re.match(libname) and \
- not "libobjc." in libname and \
- not "libSystem." in libname and \
- not "libc." in libname and \
- not "libgcc." in libname and \
- not os.path.basename(libname) == 'Python' and \
- not os.path.basename(objfile) in libname and \
- not "libswift" in libname
-
-def otool(objfile):
- command = "otool -L '%s' | grep -e '\t' | awk '{ print $1 }'" % objfile
- output = subprocess.check_output(command, shell = True, universal_newlines=True)
- return set(filter(partial(is_user_lib, objfile), output.split()))
-
-def get_rpaths_dev_tools(binary):
- command = "otool -l '%s' | grep -A2 LC_RPATH | grep path | grep \"Xcode\|CommandLineTools\"" % binary
- result = subprocess.check_output(command, shell = True, universal_newlines=True)
- pathRe = re.compile("^\s*path (.*) \(offset \d*\)$")
- output = []
-
- for line in result.splitlines():
- output.append(pathRe.search(line).group(1).strip())
-
- return output
-
-def install_name_tool_change(old, new, objfile):
- subprocess.call(["install_name_tool", "-change", old, new, objfile])
-
-def install_name_tool_id(name, objfile):
- subprocess.call(["install_name_tool", "-id", name, objfile])
-
-def install_name_tool_add_rpath(rpath, binary):
- subprocess.call(["install_name_tool", "-add_rpath", rpath, binary])
-
-def install_name_tool_delete_rpath(rpath, binary):
- subprocess.call(["install_name_tool", "-delete_rpath", rpath, binary])
-
-def libraries(objfile, result = dict()):
- libs_list = otool(objfile)
- result[objfile] = libs_list
-
- for lib in libs_list:
- if lib not in result:
- libraries(lib, result)
-
- return result
-
-def lib_path(binary):
- return os.path.join(os.path.dirname(binary), 'lib')
-
-def lib_name(lib):
- return os.path.join("@executable_path", "lib", os.path.basename(lib))
-
-def process_libraries(libs_dict, binary):
- libs_set = set(libs_dict)
- # Remove binary from libs_set to prevent a duplicate of the binary being
- # added to the libs directory.
- libs_set.remove(binary)
-
- for src in libs_set:
- name = lib_name(src)
- dst = os.path.join(lib_path(binary), os.path.basename(src))
-
- shutil.copy(src, dst)
- os.chmod(dst, 0o755)
- install_name_tool_id(name, dst)
-
- if src in libs_dict[binary]:
- install_name_tool_change(src, name, binary)
-
- for p in libs_set:
- if p in libs_dict[src]:
- install_name_tool_change(p, lib_name(p), dst)
-
-def process_swift_libraries(binary):
- command = ['xcrun', '--find', 'swift-stdlib-tool']
- swiftStdlibTool = subprocess.check_output(command, universal_newlines=True).strip()
- # from xcode11 on the dynamic swift libs reside in a separate directory from
- # the std one, might need versioned paths for future swift versions
- swiftLibPath = os.path.join(swiftStdlibTool, '../../lib/swift-5.0/macosx')
- swiftLibPath = os.path.abspath(swiftLibPath)
-
- command = [swiftStdlibTool, '--copy', '--platform', 'macosx', '--scan-executable', binary, '--destination', lib_path(binary)]
-
- if os.path.exists(swiftLibPath):
- command.extend(['--source-libraries', swiftLibPath])
-
- subprocess.check_output(command, universal_newlines=True)
-
- print(">> setting additional rpath for swift libraries")
- install_name_tool_add_rpath("@executable_path/lib", binary)
-
-def remove_dev_tools_rapths(binary):
- for path in get_rpaths_dev_tools(binary):
- install_name_tool_delete_rpath(path, binary)
-
-def main():
- binary = os.path.abspath(sys.argv[1])
- if not os.path.exists(lib_path(binary)):
- os.makedirs(lib_path(binary))
- print(">> gathering all linked libraries")
- libs = libraries(binary)
-
- print(">> copying and processing all linked libraries")
- process_libraries(libs, binary)
-
- print(">> removing rpath definitions towards dev tools")
- remove_dev_tools_rapths(binary)
-
- print(">> copying and processing swift libraries")
- process_swift_libraries(binary)
-
-if __name__ == "__main__":
- main()
diff --git a/TOOLS/dylib_unhell.py b/TOOLS/dylib_unhell.py
new file mode 100755
index 0000000000..c885969284
--- /dev/null
+++ b/TOOLS/dylib_unhell.py
@@ -0,0 +1,268 @@
+#!/usr/bin/env python3
+
+import re
+import os
+import sys
+import shutil
+import subprocess
+import json
+from functools import partial
+
+sys_re = re.compile("^/System")
+usr_re = re.compile("^/usr/lib/")
+exe_re = re.compile("@executable_path")
+
+def is_user_lib(objfile, libname):
+ return not sys_re.match(libname) and \
+ not usr_re.match(libname) and \
+ not exe_re.match(libname) and \
+ not "libobjc." in libname and \
+ not "libSystem." in libname and \
+ not "libc." in libname and \
+ not "libgcc." in libname and \
+ not os.path.basename(libname) == 'Python' and \
+ not os.path.basename(objfile) in libname and \
+ not "libswift" in libname
+
+def otool(objfile, rapths):
+ command = "otool -L '%s' | grep -e '\t' | awk '{ print $1 }'" % objfile
+ output = subprocess.check_output(command, shell = True, universal_newlines=True)
+ libs = set(filter(partial(is_user_lib, objfile), output.split()))
+
+ libs_resolved = set()
+ libs_relative = set()
+ for lib in libs:
+ lib_path = resolve_lib_path(objfile, lib, rapths)
+ libs_resolved.add(lib_path)
+ if lib_path != lib:
+ libs_relative.add(lib)
+
+ return libs_resolved, libs_relative
+
+def get_rapths(objfile):
+ rpaths = []
+ command = "otool -l '%s' | grep -A2 LC_RPATH | grep path" % objfile
+ pathRe = re.compile(r"^\s*path (.*) \(offset \d*\)$")
+
+ try:
+ result = subprocess.check_output(command, shell = True, universal_newlines=True)
+ except:
+ return rpaths
+
+ for line in result.splitlines():
+ line_clean = pathRe.search(line).group(1).strip()
+ # resolve @loader_path
+ if line_clean.startswith('@loader_path/'):
+ line_clean = line_clean[len('@loader_path/'):]
+ line_clean = os.path.normpath(os.path.join(os.path.dirname(objfile), line_clean))
+ rpaths.append(line_clean)
+
+ return rpaths
+
+def get_rpaths_dev_tools(binary):
+ command = "otool -l '%s' | grep -A2 LC_RPATH | grep path | grep \"Xcode\\|CommandLineTools\"" % binary
+ result = subprocess.check_output(command, shell = True, universal_newlines=True)
+ pathRe = re.compile(r"^\s*path (.*) \(offset \d*\)$")
+ output = []
+
+ for line in result.splitlines():
+ output.append(pathRe.search(line).group(1).strip())
+
+ return output
+
+def resolve_lib_path(objfile, lib, rapths):
+ if os.path.exists(lib):
+ return lib
+
+ if lib.startswith('@rpath/'):
+ lib = lib[len('@rpath/'):]
+ for rpath in rapths:
+ lib_path = os.path.join(rpath, lib)
+ if os.path.exists(lib_path):
+ return lib_path
+ elif lib.startswith('@loader_path/'):
+ lib = lib[len('@loader_path/'):]
+ lib_path = os.path.normpath(os.path.join(objfile, lib))
+ if os.path.exists(lib_path):
+ return lib_path
+
+ raise Exception('Could not resolve library: ' + lib)
+
+def check_vulkan_max_version(version):
+ try:
+ result = subprocess.check_output("pkg-config vulkan --max-version=" + version, shell = True)
+ return True
+ except:
+ return False
+
+def get_homebrew_prefix():
+ # set default to standard ARM path, intel path is already in the vulkan loader search array
+ result = "/opt/homebrew"
+ try:
+ result = subprocess.check_output("brew --prefix", universal_newlines=True, shell=True, stderr=subprocess.DEVNULL).strip()
+ except:
+ pass
+
+ return result
+
+def install_name_tool_change(old, new, objfile):
+ subprocess.call(["install_name_tool", "-change", old, new, objfile], stderr=subprocess.DEVNULL)
+
+def install_name_tool_id(name, objfile):
+ subprocess.call(["install_name_tool", "-id", name, objfile], stderr=subprocess.DEVNULL)
+
+def install_name_tool_add_rpath(rpath, binary):
+ subprocess.call(["install_name_tool", "-add_rpath", rpath, binary])
+
+def install_name_tool_delete_rpath(rpath, binary):
+ subprocess.call(["install_name_tool", "-delete_rpath", rpath, binary])
+
+def libraries(objfile, result = dict(), result_relative = set(), rapths = []):
+ rapths = get_rapths(objfile) + rapths
+ libs_list, libs_relative = otool(objfile, rapths)
+ result[objfile] = libs_list
+ result_relative |= libs_relative
+
+ for lib in libs_list:
+ if lib not in result:
+ libraries(lib, result, result_relative, rapths)
+
+ return result, result_relative
+
+def lib_path(binary):
+ return os.path.join(os.path.dirname(binary), 'lib')
+
+def resources_path(binary):
+ return os.path.join(os.path.dirname(binary), '../Resources')
+
+def lib_name(lib):
+ return os.path.join("@executable_path", "lib", os.path.basename(lib))
+
+def process_libraries(libs_dict, libs_dyn, binary):
+ libs_set = set(libs_dict)
+ # Remove binary from libs_set to prevent a duplicate of the binary being
+ # added to the libs directory.
+ libs_set.remove(binary)
+
+ for src in libs_set:
+ name = lib_name(src)
+ dst = os.path.join(lib_path(binary), os.path.basename(src))
+
+ shutil.copy(src, dst)
+ os.chmod(dst, 0o755)
+ install_name_tool_id(name, dst)
+
+ if src in libs_dict[binary]:
+ install_name_tool_change(src, name, binary)
+
+ for p in libs_set:
+ if p in libs_dict[src]:
+ install_name_tool_change(p, lib_name(p), dst)
+
+ for lib in libs_dyn:
+ install_name_tool_change(lib, lib_name(lib), dst)
+
+ for lib in libs_dyn:
+ install_name_tool_change(lib, lib_name(lib), binary)
+
+def process_swift_libraries(binary):
+ command = ['xcrun', '--find', 'swift-stdlib-tool']
+ swiftStdlibTool = subprocess.check_output(command, universal_newlines=True).strip()
+ # from xcode11 on the dynamic swift libs reside in a separate directory from
+ # the std one, might need versioned paths for future swift versions
+ swiftLibPath = os.path.join(swiftStdlibTool, '../../lib/swift-5.0/macosx')
+ swiftLibPath = os.path.abspath(swiftLibPath)
+
+ command = [swiftStdlibTool, '--copy', '--platform', 'macosx', '--scan-executable', binary, '--destination', lib_path(binary)]
+
+ if os.path.exists(swiftLibPath):
+ command.extend(['--source-libraries', swiftLibPath])
+
+ subprocess.check_output(command, universal_newlines=True)
+
+ print(">> setting additional rpath for swift libraries")
+ install_name_tool_add_rpath("@executable_path/lib", binary)
+
+def process_vulkan_loader(binary, loaderName, loaderRelativeFolder, libraryNode):
+ # https://github.com/KhronosGroup/Vulkan-Loader/blob/main/docs/LoaderDriverInterface.md#example-macos-driver-search-path
+ # https://github.com/KhronosGroup/Vulkan-Loader/blob/main/docs/LoaderLayerInterface.md#macos-layer-discovery
+ loaderSystemSearchFolders = [
+ os.path.join(os.path.expanduser("~"), ".config", loaderRelativeFolder),
+ os.path.join("/etc/xdg", loaderRelativeFolder),
+ os.path.join("/usr/local/etc", loaderRelativeFolder),
+ os.path.join("/etc", loaderRelativeFolder),
+ os.path.join(os.path.expanduser("~"), ".local/share", loaderRelativeFolder),
+ os.path.join("/usr/local/share", loaderRelativeFolder),
+ os.path.join("/usr/share/vulkan", loaderRelativeFolder),
+ os.path.join(get_homebrew_prefix(), 'share', loaderRelativeFolder),
+ ]
+
+ loaderSystemFolder = ""
+ for loaderSystemSearchFolder in loaderSystemSearchFolders:
+ if os.path.exists(loaderSystemSearchFolder):
+ loaderSystemFolder = loaderSystemSearchFolder
+ break
+
+ if not loaderSystemFolder:
+ print(">>> could not find loader folder " + loaderRelativeFolder)
+ return
+
+ loaderBundleFolder = os.path.join(resources_path(binary), loaderRelativeFolder)
+ loaderSystemPath = os.path.join(loaderSystemFolder, loaderName)
+ loaderBundlePath = os.path.join(loaderBundleFolder, loaderName)
+ libraryRelativeFolder = "../../../Frameworks/"
+
+ if not os.path.exists(loaderSystemPath):
+ print(">>> could not find loader " + loaderName)
+ return
+
+ if not os.path.exists(loaderBundleFolder):
+ os.makedirs(loaderBundleFolder)
+
+ loaderSystemFile = open(loaderSystemPath, 'r')
+ loaderJsonData = json.load(loaderSystemFile)
+ librarySystemPath = os.path.join(loaderSystemFolder, loaderJsonData[libraryNode]["library_path"])
+
+ if not os.path.exists(librarySystemPath):
+ print(">>> could not find loader library " + librarySystemPath)
+ return
+
+ print(">>> modifiying and writing loader json " + loaderName)
+ loaderBundleFile = open(loaderBundlePath, 'w')
+ loaderLibraryName = os.path.basename(librarySystemPath)
+ loaderJsonData[libraryNode]["library_path"] = os.path.join(libraryRelativeFolder, loaderLibraryName)
+ json.dump(loaderJsonData, loaderBundleFile, indent=4)
+
+ print(">>> copying loader library " + loaderLibraryName)
+ frameworkBundleFolder = os.path.join(loaderBundleFolder, libraryRelativeFolder)
+ if not os.path.exists(frameworkBundleFolder):
+ os.makedirs(frameworkBundleFolder)
+ shutil.copy(librarySystemPath, os.path.join(frameworkBundleFolder, loaderLibraryName))
+
+def remove_dev_tools_rapths(binary):
+ for path in get_rpaths_dev_tools(binary):
+ install_name_tool_delete_rpath(path, binary)
+
+def process(binary):
+ binary = os.path.abspath(binary)
+ if not os.path.exists(lib_path(binary)):
+ os.makedirs(lib_path(binary))
+ print(">> gathering all linked libraries")
+ libs, libs_rel = libraries(binary)
+
+ print(">> copying and processing all linked libraries")
+ process_libraries(libs, libs_rel, binary)
+
+ print(">> removing rpath definitions towards dev tools")
+ remove_dev_tools_rapths(binary)
+
+ print(">> copying and processing swift libraries")
+ process_swift_libraries(binary)
+
+ print(">> copying and processing vulkan loader")
+ process_vulkan_loader(binary, "MoltenVK_icd.json", "vulkan/icd.d", "ICD")
+ if check_vulkan_max_version("1.3.261.1"):
+ process_vulkan_loader(binary, "VkLayer_khronos_synchronization2.json", "vulkan/explicit_layer.d", "layer")
+
+if __name__ == "__main__":
+ process(sys.argv[1])
diff --git a/TOOLS/file2string.py b/TOOLS/file2string.py
index b40317218c..5b1c4a95d1 100755
--- a/TOOLS/file2string.py
+++ b/TOOLS/file2string.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Convert the contents of a file into a C string constant.
# Note that the compiler will implicitly add an extra 0 byte at the end
@@ -22,27 +22,23 @@
# License along with mpv. If not, see <http://www.gnu.org/licenses/>.
#
-from __future__ import unicode_literals
import sys
-# Indexing a byte string yields int on Python 3.x, and a str on Python 2.x
-def pord(c):
- return ord(c) if type(c) == str else c
-
def file2string(infilename, infile, outfile):
outfile.write("// Generated from %s\n\n" % infilename)
- conv = ['\\' + ("%03o" % c) for c in range(256)]
+ conv = ["\\%03o" % c for c in range(256)]
safe_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" \
- "0123456789!#%&'()*+,-./:;<=>?[]^_{|}~ "
+ "0123456789!#%&'()*+,-./:;<=>[]^_{|}~ "
for c in safe_chars:
conv[ord(c)] = c
for c, esc in ("\nn", "\tt", r"\\", '""'):
conv[ord(c)] = '\\' + esc
for line in infile:
- outfile.write('"' + ''.join(conv[pord(c)] for c in line) + '"\n')
+ outfile.write('"' + ''.join(conv[c] for c in line) + '"\n')
if __name__ == "__main__":
+ outfile = open(sys.argv[2], "w")
with open(sys.argv[1], 'rb') as infile:
- file2string(sys.argv[1], infile, sys.stdout)
+ file2string(sys.argv[1], infile, outfile)
diff --git a/TOOLS/gen-interface-changes.py b/TOOLS/gen-interface-changes.py
new file mode 100755
index 0000000000..7f5435e216
--- /dev/null
+++ b/TOOLS/gen-interface-changes.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+
+# Generate a new interface-changes.rst based on the entries in
+# the interface-changes directory.
+
+#
+# This file is part of mpv.
+#
+# mpv is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# mpv is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with mpv. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import pathlib
+import sys
+from shutil import which
+from subprocess import check_output
+
+def add_new_entries(docs_dir, out, git):
+ changes_dir = pathlib.Path(docs_dir) / "interface-changes"
+ files = []
+ for f in pathlib.Path(changes_dir).glob("*.txt"):
+ if f.is_file() and not f.name == "example.txt":
+ timestamp = check_output([git, "log", "--format=%ct", "-n", "1", "--",
+ f], encoding="UTF-8")
+ if timestamp:
+ files.append((f, timestamp))
+ else:
+ print(f"Skipping file not tracked by git: {f.name}")
+
+ files.sort(key=lambda x: x[1])
+ for file in files:
+ with open(file[0].resolve(), "r") as f:
+ for line in f:
+ line = " - " + line.rstrip()
+ out.write(line + "\n")
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2:
+ print(f"Usage: {sys.argv[0]} <version>")
+ sys.exit(1)
+
+ git = which('git')
+ if not git:
+ print("Unable to find git binary")
+ sys.exit(1)
+
+ # Accept passing only the major version number and the full 0 version.
+ major_version = -1
+ if sys.argv[1].isdigit():
+ major_version = sys.argv[1]
+ else:
+ ver_split = sys.argv[1].split(".")
+ if len(ver_split) == 3 and ver_split[1].isdigit():
+ major_version = ver_split[1]
+
+ if major_version == -1:
+ print(f"Invalid version number: {sys.argv[1]}")
+ sys.exit(1)
+
+ docs_dir = pathlib.Path(sys.argv[0]).resolve().parents[1] / "DOCS"
+ interface_changes = docs_dir / "interface-changes.rst"
+ with open(interface_changes, "r") as f:
+ lines = [line.rstrip() for line in f]
+
+ ver_line = " --- mpv 0." + major_version + ".0 ---"
+ next_ver_line = " --- mpv 0." + str(int(major_version) + 1) + ".0 ---"
+ with open(interface_changes, "w", newline="\n") as f:
+ for line in lines:
+ if line == ver_line:
+ f.write(next_ver_line + "\n")
+ f.write(line + "\n")
+ if line == ver_line:
+ add_new_entries(docs_dir, f, git)
diff --git a/TOOLS/idet.sh b/TOOLS/idet.sh
index 46bb835832..7fb51c16d8 100755
--- a/TOOLS/idet.sh
+++ b/TOOLS/idet.sh
@@ -22,7 +22,7 @@
testfun()
{
$ILDETECT_MPV "$@" \
- --vf-add=lavfi="[idet]" --msg-level ffmpeg=v \
+ --vf-add=lavfi="[idet]" --msg-level=ffmpeg=v \
--o= --vo=null --no-audio --untimed \
$ILDETECT_MPVFLAGS \
| { if [ -n "$ILDETECT_QUIET" ]; then cat; else tee /dev/stderr; fi } \
diff --git a/TOOLS/lua/acompressor.lua b/TOOLS/lua/acompressor.lua
index 5fc5063e8d..6a6914076a 100644
--- a/TOOLS/lua/acompressor.lua
+++ b/TOOLS/lua/acompressor.lua
@@ -2,7 +2,7 @@
-- filter including key bindings for adjusting parameters.
--
-- See https://ffmpeg.org/ffmpeg-filters.html#acompressor for explanation
--- of the parameteres.
+-- of the parameters.
local mp = require 'mp'
local options = require 'mp.options'
diff --git a/TOOLS/lua/autocrop.lua b/TOOLS/lua/autocrop.lua
index af6021b75a..ea57d15658 100644
--- a/TOOLS/lua/autocrop.lua
+++ b/TOOLS/lua/autocrop.lua
@@ -1,96 +1,69 @@
--[[
-This script uses the lavfi cropdetect filter to automatically
-insert a crop filter with appropriate parameters for the
-currently playing video.
-
-It will automatically crop the video, when playback starts.
-
-Also It registers the key-binding "C" (shift+c). You can manually
-crop the video by pressing the "C" (shift+c) key.
-
-If the "C" key is pressed again, the crop filter is removed
-restoring playback to its original state.
-
-The workflow is as follows: First, it inserts the filter
-vf=lavfi=cropdetect. After <detect_seconds> (default is 1)
-seconds, it then inserts the filter vf=crop=w:h:x:y, where
-w,h,x,y are determined from the vf-metadata gathered by
-cropdetect. The cropdetect filter is removed immediately after
-the crop filter is inserted as it is no longer needed.
-
-Since the crop parameters are determined from the 1 second of
-video between inserting the cropdetect and crop filters, the "C"
-key should be pressed at a position in the video where the crop
-region is unambiguous (i.e., not a black frame, black background
-title card, or dark scene).
-
-The default options can be overridden by adding
-script-opts-append=autocrop-<parameter>=<value> into mpv.conf
-
-List of available parameters (For default values, see <options>):
-
-auto: bool - Whether to automatically apply crop at the start of
- playback. If you don't want to crop automatically, set it to
- false or add "script-opts-append=autocrop-auto=no" into
- mpv.conf.
-
-auto_delay: seconds - Delay before starting crop in auto mode.
- You can try to increase this value to avoid dark scene or
- fade in at beginning. Automatic cropping will not occur if
- the value is larger than the remaining playback time.
-
-detect_limit: number[0-255] - Black threshold for cropdetect.
- Smaller values will generally result in less cropping.
- See limit of https://ffmpeg.org/ffmpeg-filters.html#cropdetect
-
-detect_round: number[2^n] - The value which the width/height
- should be divisible by. Smaller values ​​have better detection
- accuracy. If you have problems with other filters,
- you can try to set it to 4 or 16.
- See round of https://ffmpeg.org/ffmpeg-filters.html#cropdetect
-
-detect_min_ratio: number[0.0-1.0] - The ratio of the minimum clip
- size to the original. If the picture is over cropped or under
- cropped, try adjusting this value.
-
-detect_seconds: seconds - How long to gather cropdetect data.
- Increasing this may be desirable to allow cropdetect more
- time to collect data.
---]]
+This script uses the lavfi cropdetect filter and the video-crop property to
+automatically crop the currently playing video with appropriate parameters.
+
+It automatically crops the video when playback starts.
+
+You can also manually crop the video by pressing the "C" (shift+c) key.
+Pressing it again undoes the crop.
-require "mp.msg"
-require 'mp.options'
+The workflow is as follows: First, it inserts the cropdetect filter. After
+<detect_seconds> (default is 1) seconds, it then sets video-crop based on the
+vf-metadata values gathered by cropdetect. The cropdetect filter is removed
+after video-crop is set as it is no longer needed.
+Since the crop parameters are determined from the 1 second of video between
+inserting the cropdetect filter and setting video-crop, the "C" key should be
+pressed at a position in the video where the crop region is unambiguous (i.e.,
+not a black frame, black background title card, or dark scene).
+
+If non-copy-back hardware decoding is in use, hwdec is temporarily disabled for
+the duration of cropdetect as the filter would fail otherwise.
+
+These are the default options. They can be overridden by adding
+script-opts-append=autocrop-<parameter>=<value> to mpv.conf.