PR #21059 opened by Timo Rothenpieler (BtbN)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21059
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21059.patch


>From 9205963cb3ddc6c020c0ca34c2d5b8dadc7f9a15 Mon Sep 17 00:00:00 2001
From: Timo Rothenpieler <[email protected]>
Date: Sun, 30 Nov 2025 16:25:19 +0100
Subject: [PATCH] forgejo: backport CI to release/7.1

---
 .forgejo/pre-commit/config.yaml       |  36 ++++
 .forgejo/pre-commit/ignored-words.txt | 119 +++++++++++++
 .forgejo/workflows/lint.yml           |  26 +++
 .forgejo/workflows/test.yml           |  76 ++++++++
 tools/check_arm_indent.sh             |  55 ++++++
 tools/indent_arm_assembly.pl          | 243 ++++++++++++++++++++++++++
 6 files changed, 555 insertions(+)
 create mode 100644 .forgejo/pre-commit/config.yaml
 create mode 100644 .forgejo/pre-commit/ignored-words.txt
 create mode 100644 .forgejo/workflows/lint.yml
 create mode 100644 .forgejo/workflows/test.yml
 create mode 100755 tools/check_arm_indent.sh
 create mode 100755 tools/indent_arm_assembly.pl

diff --git a/.forgejo/pre-commit/config.yaml b/.forgejo/pre-commit/config.yaml
new file mode 100644
index 0000000000..f1ab7765ef
--- /dev/null
+++ b/.forgejo/pre-commit/config.yaml
@@ -0,0 +1,36 @@
+exclude: ^tests/ref/
+
+repos:
+- repo: https://github.com/pre-commit/pre-commit-hooks
+  rev: v5.0.0
+  hooks:
+    - id: check-case-conflict
+    - id: check-executables-have-shebangs
+    - id: check-illegal-windows-names
+    - id: check-shebang-scripts-are-executable
+    - id: check-yaml
+    - id: end-of-file-fixer
+    - id: file-contents-sorter
+      files:
+        .forgejo/pre-commit/ignored-words.txt
+      args:
+        - --ignore-case
+    - id: fix-byte-order-marker
+    - id: mixed-line-ending
+    - id: trailing-whitespace
+- repo: local
+  hooks:
+    - id: aarch64-asm-indent
+      name: fix aarch64 assembly indentation
+      files: ^.*/aarch64/.*\.S$
+      language: script
+      entry: ./tools/check_arm_indent.sh --apply
+      pass_filenames: false
+- repo: https://github.com/codespell-project/codespell
+  rev: v2.4.1
+  hooks:
+    - id: codespell
+      args:
+        - --ignore-words=.forgejo/pre-commit/ignored-words.txt
+        - --ignore-multiline-regex=codespell:off.*?(codespell:on|\Z)
+      exclude: ^tools/(patcheck|clean-diff)$
diff --git a/.forgejo/pre-commit/ignored-words.txt 
b/.forgejo/pre-commit/ignored-words.txt
new file mode 100644
index 0000000000..870fd96be3
--- /dev/null
+++ b/.forgejo/pre-commit/ignored-words.txt
@@ -0,0 +1,119 @@
+abl
+ACN
+acount
+addin
+alis
+alls
+ALOG
+ALS
+als
+ANC
+anc
+ANS
+ans
+anull
+basf
+bloc
+brane
+BREIF
+BU
+bu
+bufer
+CAF
+caf
+clen
+clens
+Collet
+compre
+dum
+endin
+erro
+FIEL
+fiel
+filp
+fils
+FILTERD
+filterd
+fle
+fo
+FPR
+fro
+Hald
+indx
+ine
+inh
+inout
+inouts
+inport
+ist
+LAF
+laf
+lastr
+LinS
+mapp
+mis
+mot
+nd
+nIn
+offsetp
+orderd
+ot
+outout
+padd
+PAETH
+paeth
+PARM
+parm
+parms
+pEvents
+PixelX
+Psot
+quater
+readd
+recuse
+redY
+Reencode
+reencode
+remaind
+renderD
+rin
+SAV
+SEH
+SER
+ser
+setts
+shft
+SIZ
+siz
+skipd
+sme
+som
+sover
+STAP
+startd
+statics
+struc
+suble
+TE
+tE
+te
+tha
+tne
+tolen
+tpye
+tre
+TRUN
+trun
+truns
+Tung
+TYE
+ue
+UES
+ues
+vai
+vas
+vie
+VILL
+vor
+wel
+wih
diff --git a/.forgejo/workflows/lint.yml b/.forgejo/workflows/lint.yml
new file mode 100644
index 0000000000..4cdbc08057
--- /dev/null
+++ b/.forgejo/workflows/lint.yml
@@ -0,0 +1,26 @@
+on:
+  push:
+    branches:
+      - release/7.1
+  pull_request:
+
+jobs:
+  lint:
+    runs-on: utilities
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+      - name: Install pre-commit CI
+        id: install
+        run: |
+            python3 -m venv ~/pre-commit
+            ~/pre-commit/bin/pip install --upgrade pip setuptools
+            ~/pre-commit/bin/pip install pre-commit
+            echo "envhash=$({ python3 --version && cat 
.forgejo/pre-commit/config.yaml; } | sha256sum | cut -d' ' -f1)" >> 
$FORGEJO_OUTPUT
+      - name: Cache
+        uses: actions/cache@v4
+        with:
+          path: ~/.cache/pre-commit
+          key: pre-commit-${{ steps.install.outputs.envhash }}
+      - name: Run pre-commit CI
+        run: ~/pre-commit/bin/pre-commit run -c 
.forgejo/pre-commit/config.yaml --show-diff-on-failure --color=always 
--all-files
diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml
new file mode 100644
index 0000000000..2b41d486ba
--- /dev/null
+++ b/.forgejo/workflows/test.yml
@@ -0,0 +1,76 @@
+on:
+  push:
+    branches:
+      - release/7.1
+  pull_request:
+
+jobs:
+  run_fate:
+    strategy:
+      fail-fast: false
+      matrix:
+        runner: [linux-aarch64]
+        shared: ['static']
+        bits: ['64']
+        include:
+          - runner: linux-amd64
+            shared: 'static'
+            bits: '32'
+          - runner: linux-amd64
+            shared: 'shared'
+            bits: '64'
+    runs-on: ${{ matrix.runner }}
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+      - name: Configure
+        run: |
+          ./configure --enable-gpl --enable-nonfree --enable-memory-poisoning 
--assert-level=2 \
+              $([ "${{ matrix.bits }}" != "32" ] || echo --arch=x86_32 
--extra-cflags=-m32 --extra-cxxflags=-m32 --extra-ldflags=-m32) \
+              $([ "${{ matrix.shared }}" != "shared" ] || echo --enable-shared 
--disable-static) \
+              || CFGRES=$? && CFGRES=$?
+          cat ffbuild/config.log
+          exit $CFGRES
+      - name: Build
+        run: make -j$(nproc)
+      - name: Restore Cached Fate-Suite
+        id: cache
+        uses: actions/cache/restore@v4
+        with:
+          path: fate-suite
+          key: fate-suite
+          restore-keys: |
+            fate-suite-
+      - name: Sync Fate-Suite
+        id: fate
+        run: |
+          make fate-rsync SAMPLES=$PWD/fate-suite
+          echo "hash=$(find fate-suite -type f -printf "%P %s %T@\n" | sort | 
sha256sum | cut -d' ' -f1)" >> $FORGEJO_OUTPUT
+      - name: Cache Fate-Suite
+        uses: actions/cache/save@v4
+        if: ${{ format('fate-suite-{0}', steps.fate.outputs.hash) != 
steps.cache.outputs.cache-matched-key }}
+        with:
+          path: fate-suite
+          key: fate-suite-${{ steps.fate.outputs.hash }}
+      - name: Run Fate
+        run: LD_LIBRARY_PATH="$(printf "%s:" "$PWD"/lib*)$PWD" make fate 
fate-build SAMPLES=$PWD/fate-suite -j$(nproc)
+  compile_only:
+    strategy:
+      fail-fast: false
+      matrix:
+        image: ["ghcr.io/btbn/ffmpeg-builds/win64-gpl:latest"]
+    runs-on: linux-amd64
+    container: ${{ matrix.image }}
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+      - name: Configure
+        run: |
+          ./configure --pkg-config-flags="--static" $FFBUILD_TARGET_FLAGS 
$FF_CONFIGURE \
+              --cc="$CC" --cxx="$CXX" --ar="$AR" --ranlib="$RANLIB" --nm="$NM" 
\
+              --extra-cflags="$FF_CFLAGS" --extra-cxxflags="$FF_CXXFLAGS" \
+              --extra-libs="$FF_LIBS" --extra-ldflags="$FF_LDFLAGS" 
--extra-ldexeflags="$FF_LDEXEFLAGS"
+      - name: Build
+        run: make -j$(nproc)
+      - name: Run Fate
+        run: make -j$(nproc) fate-build
diff --git a/tools/check_arm_indent.sh b/tools/check_arm_indent.sh
new file mode 100755
index 0000000000..5becfe0aec
--- /dev/null
+++ b/tools/check_arm_indent.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+# Copyright (c) 2025 Martin Storsjo
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, 
this
+#    list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+#    this list of conditions and the following disclaimer in the documentation
+#    and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+cd $(dirname $0)/..
+
+if [ "$1" = "--apply" ]; then
+    apply=1
+fi
+
+ret=0
+
+for i in */aarch64/*.S */aarch64/*/*.S; do
+    case $i in
+        
libavcodec/aarch64/h264idct_neon.S|libavcodec/aarch64/h26x/epel_neon.S|libavcodec/aarch64/h26x/qpel_neon.S|libavcodec/aarch64/vc1dsp_neon.S)
+        # Skip files with known (and tolerated) deviations from the tool.
+        continue
+    esac
+    ./tools/indent_arm_assembly.pl < "$i" > tmp.S || ret=$?
+    if ! git diff --quiet --no-index "$i" tmp.S; then
+        if [ -n "$apply" ]; then
+            mv tmp.S "$i"
+        else
+            git --no-pager diff --no-index "$i" tmp.S
+        fi
+        ret=1
+    fi
+done
+
+rm -f tmp.S
+
+exit $ret
diff --git a/tools/indent_arm_assembly.pl b/tools/indent_arm_assembly.pl
new file mode 100755
index 0000000000..359c2bcf4f
--- /dev/null
+++ b/tools/indent_arm_assembly.pl
@@ -0,0 +1,243 @@
+#!/usr/bin/env perl
+#
+# Copyright (c) 2025 Martin Storsjo
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, 
this
+#    list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+#    this list of conditions and the following disclaimer in the documentation
+#    and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+# A script for reformatting ARM/AArch64 assembly according to the following
+# style:
+# - Instructions start after 8 columns, operands start after 24 columns
+# - Vector register layouts and modifiers like "uxtw" are written in lowercase
+# - Optionally align operand columns vertically according to their
+#   maximum width (accommodating for e.g. x0 vs x10, or v0.8b vs v16.16b).
+#
+# The script can be executed as "indent_arm_assembly.pl file [outfile]".
+# If no outfile is specified, the given file is overwritten in place.
+#
+# Alternatively, the if no file parameters are given, the script reads input
+# code on stdin, and outputs the reformatted code on stdout.
+
+use strict;
+
+my $indent_operands = 0;
+my $instr_indent = 8;
+my $operand_indent = 24;
+my $match_indent = 0;
+my $file;
+my $outfile;
+
+while (@ARGV) {
+    my $opt = shift;
+
+    if ($opt eq "-operands") {
+        $indent_operands = 1;
+    } elsif ($opt eq "-indent") {
+        $instr_indent = shift;
+    } elsif ($opt eq "-operand-indent") {
+        $operand_indent = shift;
+    } elsif ($opt eq "-match-indent") {
+        $match_indent = 1;
+    } else {
+        if (!$file) {
+            $file = $opt;
+        } elsif (!$outfile) {
+            $outfile = $opt;
+        } else {
+            die "Unrecognized parameter $opt\n";
+        }
+    }
+}
+
+if ($operand_indent < $instr_indent) {
+    die "Can't indent operands to $operand_indent while indenting " .
+        "instructions to $instr_indent\n";
+}
+
+# Return a string consisting of n spaces
+sub spaces {
+    my $n = $_[0];
+    return " " x $n;
+}
+
+sub indentcolumns {
+    my $input = $_[0];
+    my $chars = $_[1];
+    my @operands = split(/,/, $input);
+    my $num = @operands;
+    my $ret = "";
+    for (my $i = 0; $i < $num; $i++) {
+        my $cur = $operands[$i];
+        # Trim out leading/trailing whitespace
+        $cur =~ s/^\s+|\s+$//g;
+        $ret .= $cur;
+        if ($i + 1 < $num) {
+            # If we have a following operand, add a comma and whitespace to
+            # align the next operand.
+            my $next = $operands[$i+1];
+            my $len = length($cur);
+            if ($len > $chars) {
+                # If this operand was too wide for the intended column width,
+                # don't try to realign the line at all, just return the input
+                # untouched.
+                return $input;
+            }
+            my $pad = $chars - $len;
+            if ($next =~ /[su]xt[bhw]|[la]s[lr]/) {
+                # If the next item isn't a regular operand, but a modifier,
+                # don't try to align that. E.g. "add x0,  x0,  w1, uxtw #1".
+                $pad = 0;
+            }
+            $ret .= "," . spaces(1 + $pad);
+        }
+    }
+    return $ret;
+}
+
+# Realign the operands part of an instruction line, making each operand
+# take up the maximum width for that kind of operand.
+sub columns {
+    my $rest = $_[0];
+    if ($rest !~ /,/) {
+        # No commas, no operands to split and align
+        return $rest;
+    }
+    if ($rest =~ /{|[^\w]\[/) {
+        # Check for instructions that use register ranges, like {v0.8b,v1.8b}
+        # or mem address operands, like "ldr x0, [sp]" - we skip trying to
+        # realign these.
+        return $rest;
+    }
+    if ($rest =~ /v[0-9]+\.[0-9]+[bhsd]/) {
+        # If we have references to aarch64 style vector registers, like
+        # v0.8b, then align all operands to the maximum width of such
+        # operands - v16.16b.
+        #
+        # TODO: Ideally, we'd handle mixed operand types individually.
+        return indentcolumns($rest, 7);
+    }
+    # Indent operands according to the maximum width of regular registers,
+    # like x10.
+    return indentcolumns($rest, 3);
+}
+
+my $in;
+my $out;
+my $tempfile;
+
+if ($file) {
+    open(INPUT, "$file") or die "Unable to open $file: $!";
+    $in = *INPUT;
+    if ($outfile) {
+        open(OUTPUT, ">$outfile") or die "Unable to open $outfile: $!";
+    } else {
+        $tempfile = "$file.tmp";
+        open(OUTPUT, ">$tempfile") or die "Unable to open $tempfile: $!";
+    }
+    $out = *OUTPUT;
+} else {
+    $in = *STDIN;
+    $out = *STDOUT;
+}
+
+while (<$in>) {
+    # Trim off trailing whitespace.
+    chomp;
+    if (/^([\.\w\d]+:)?(\s+)([\w\\][\w\\\.]*)(?:(\s+)(.*)|$)/) {
+        my $label = $1;
+        my $indent = $2;
+        my $instr = $3;
+        my $origspace = $4;
+        my $rest = $5;
+
+        my $orig_operand_indent = length($label) + length($indent) +
+                                  length($instr) + length($origspace);
+
+        if ($indent_operands) {
+            $rest = columns($rest);
+        }
+
+        my $size = $instr_indent;
+        if ($match_indent) {
+            # Try to check the current attempted indent size and normalize
+            # to it; match existing ident sizes of 4, 8, 10 and 12 columns.
+            my $cur_indent = length($label) + length($indent);
+            if ($cur_indent >= 3 && $cur_indent <= 5) {
+                $size = 4;
+            } elsif ($cur_indent >= 7 && $cur_indent <= 9) {
+                $size = 8;
+            } elsif ($cur_indent == 10 || $cur_indent == 12) {
+                $size = $cur_indent;
+            }
+        }
+        if (length($label) >= $size) {
+            # Not enough space for the label; just add a space between the 
label
+            # and the instruction.
+            $indent = " ";
+        } else {
+            $indent = spaces($size - length($label));
+        }
+
+        my $instr_end = length($label) + length($indent) + length($instr);
+        $size = $operand_indent - $instr_end;
+        if ($match_indent) {
+            # Check how the operands currently seem to be indented.
+            my $cur_indent = $orig_operand_indent;
+            if ($cur_indent >= 11 && $cur_indent <= 13) {
+                $size = 12;
+            } elsif ($cur_indent >= 14 && $cur_indent <= 17) {
+                $size = 16;
+            } elsif ($cur_indent >= 18 && $cur_indent <= 22) {
+                $size = 20;
+            } elsif ($cur_indent >= 23 && $cur_indent <= 27) {
+                $size = 24;
+            }
+            $size -= $instr_end;
+        }
+        my $operand_space = " ";
+        if ($size > 0) {
+            $operand_space = spaces($size);
+        }
+
+        # Lowercase the aarch64 vector layout description, .8B -> .8b
+        $rest =~ s/(\.[84216]*[BHSD])/lc($1)/ge;
+        # Lowercase modifiers like "uxtw" or "lsl"
+        $rest =~ s/([SU]XT[BWH]|[LA]S[LR])/lc($1)/ge;
+
+        # Reassemble the line
+        if ($rest eq "") {
+            $_ = $label . $indent . $instr;
+        } else {
+            $_ = $label . $indent . $instr . $operand_space . $rest;
+        }
+    }
+    print $out $_ . "\n";
+}
+
+if ($file) {
+    close(INPUT);
+    close(OUTPUT);
+}
+if ($tempfile) {
+    rename($tempfile, $file);
+}
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to