xref: /aosp_15_r20/external/libdav1d/tests/dav1d_argon.bash (revision c09093415860a1c2373dacd84c4fde00c507cdfd)
1#!/usr/bin/env bash
2
3DAV1D="tools/dav1d"
4ARGON_DIR='.'
5FILMGRAIN=1
6CPUMASK=-1
7THREADS=1
8JOBS=0
9WRAP=""
10FAIL_FAST=0
11
12
13usage() {
14    NAME=$(basename "$0")
15    {
16        printf "Usage:   %s [-d dav1d] [-a argondir] [-g \$filmgrain] [-c \$cpumask] [-t threads] [-j jobs] [DIRECTORY]...\n" "$NAME"
17        printf "Example: %s -d /path/to/dav1d -a /path/to/argon/ -g 0 -c avx2 profile0_core\n" "$NAME"
18        printf "Used to verify that dav1d can decode the Argon AV1 test vectors correctly.\n\n"
19        printf " DIRECTORY one or more dirs in the argon folder to check against\n"
20        printf "             (default: everything except large scale tiles and stress files)\n"
21        printf " -f        fail fast\n"
22        printf " -d dav1d  path to dav1d executable (default: tools/dav1d)\n"
23        printf " -a dir    path to argon dir (default: 'tests/argon' if found; '.' otherwise)\n"
24        printf " -g \$num   enable filmgrain (default: 1)\n"
25        printf " -c \$mask  use restricted cpumask (default: -1)\n"
26        printf " -t \$num   number of threads per dav1d (default: 1)\n"
27        printf " -j \$num   number of parallel dav1d processes (default: 0)\n"
28        printf " -w tool   execute dav1d with a wrapper tool\n\n"
29    } >&2
30    exit 1
31}
32
33error() {
34    printf "\033[1;91m%s\033[0m\n" "$*" >&2
35    exit 1
36}
37
38fail() {
39    printf "\033[1K\rMismatch in %s\n" "$1"
40    [[ $FAIL_FAST = 1 ]] && exit 1
41    (( failed++ ))
42}
43
44check_pids() {
45    new_pids=()
46    done_pids=()
47    for p in "${pids[@]}"; do
48        if kill -0 "$p" 2>/dev/null; then
49            new_pids+=("$p")
50        else
51            done_pids+=("$p")
52        fi
53    done
54    pids=("${new_pids[@]}")
55}
56
57wait_pids() {
58    pid_list=("$@")
59    for p in "${pid_list[@]}"; do
60        if ! wait "$p"; then
61            local file_varname="file$p"
62            fail "${!file_varname}"
63        fi
64    done
65}
66
67block_pids() {
68    while [ ${#pids[@]} -ge "$JOBS" ]; do
69        check_pids
70        if [ ${#done_pids} -eq 0 ]; then
71            sleep 0.2
72        else
73            wait_pids "${done_pids[@]}"
74        fi
75    done
76}
77
78wait_all_pids() {
79    wait_pids "${pids[@]}"
80}
81
82# find tests/argon
83tests_dir=$(dirname "$(readlink -f "$0")")
84if [ -d "$tests_dir/argon" ]; then
85    ARGON_DIR="$tests_dir/argon"
86fi
87
88while getopts ":d:a:g:c:t:j:w:f" opt; do
89    case "$opt" in
90        f)
91            FAIL_FAST=1
92            ;;
93        d)
94            DAV1D="$OPTARG"
95            ;;
96        a)
97            ARGON_DIR="$OPTARG"
98            ;;
99        g)
100            FILMGRAIN="$OPTARG"
101            ;;
102        c)
103            CPUMASK="$OPTARG"
104            ;;
105        t)
106            THREADS="$OPTARG"
107            ;;
108        j)
109            JOBS="$OPTARG"
110            ;;
111        w)
112            WRAP="$OPTARG"
113            ;;
114        \?)
115            printf "Error! Invalid option: -%s\n" "$OPTARG" >&2
116            usage
117            ;;
118        *)
119            usage
120            ;;
121    esac
122done
123shift $((OPTIND-1))
124
125if [ "$JOBS" -eq 0 ]; then
126    if [ "$THREADS" -gt 0 ]; then
127        JOBS="$((($( (nproc || sysctl -n hw.logicalcpu || getconf _NPROCESSORS_ONLN || echo 1) 2>/dev/null)+THREADS-1)/THREADS))"
128    else
129        JOBS=1
130    fi
131fi
132
133if [ "$#" -eq 0 ]; then
134    # Everything except large scale tiles and stress files.
135    dirs=("$ARGON_DIR/profile0_core"       "$ARGON_DIR/profile0_core_special"
136          "$ARGON_DIR/profile0_not_annexb" "$ARGON_DIR/profile0_not_annexb_special"
137          "$ARGON_DIR/profile1_core"       "$ARGON_DIR/profile1_core_special"
138          "$ARGON_DIR/profile1_not_annexb" "$ARGON_DIR/profile1_not_annexb_special"
139          "$ARGON_DIR/profile2_core"       "$ARGON_DIR/profile2_core_special"
140          "$ARGON_DIR/profile2_not_annexb" "$ARGON_DIR/profile2_not_annexb_special"
141          "$ARGON_DIR/profile_switching")
142else
143    mapfile -t dirs < <(printf "${ARGON_DIR}/%s\n" "$@" | sort -u)
144fi
145
146ver_info="dav1d $("$DAV1D" --filmgrain "$FILMGRAIN" --cpumask "$CPUMASK" --threads "$THREADS" -v 2>&1) filmgrain=$FILMGRAIN cpumask=$CPUMASK" || error "Error! Can't run $DAV1D"
147files=()
148
149for d in "${dirs[@]}"; do
150    if [ -d "$d/streams" ]; then
151        files+=("${d/%\//}"/streams/*.obu)
152    fi
153done
154
155num_files="${#files[@]}"
156if [ "$num_files" -eq 0 ]; then
157    error "Error! No files found at ${dirs[*]}"
158fi
159
160failed=0
161pids=()
162for i in "${!files[@]}"; do
163    f="${files[i]}"
164    if [ "$FILMGRAIN" -eq 0 ]; then
165        md5=${f/\/streams\//\/md5_no_film_grain\/}
166    else
167        md5=${f/\/streams\//\/md5_ref\/}
168    fi
169    md5=$(<"${md5/%obu/md5}") || error "Error! Can't read md5 ${md5} for file ${f}"
170    md5=${md5/ */}
171
172    printf '\033[1K\r[%3d%% %*d/%d] Verifying %s' "$(((i+1)*100/num_files))" "${#num_files}" "$((i+1))" "$num_files" "${f#"$ARGON_DIR"/}"
173    cmd=($WRAP "$DAV1D" -i "$f" --filmgrain "$FILMGRAIN" --verify "$md5" --cpumask "$CPUMASK" --threads "$THREADS" -q)
174    if [ "$JOBS" -gt 1 ]; then
175        "${cmd[@]}" 2>/dev/null &
176        p=$!
177        pids+=("$p")
178        declare "file$p=${f#"$ARGON_DIR"/}"
179        block_pids
180    else
181        if ! "${cmd[@]}" 2>/dev/null; then
182            fail "${f#"$ARGON_DIR"/}"
183        fi
184    fi
185done
186
187wait_all_pids
188
189if [ "$failed" -ne 0 ]; then
190    printf "\033[1K\r%d/%d files \033[1;91mfailed\033[0m to verify" "$failed" "$num_files"
191else
192    printf "\033[1K\r%d files \033[1;92msuccessfully\033[0m verified" "$num_files"
193fi
194printf " in %dm%ds (%s)\n" "$((SECONDS/60))" "$((SECONDS%60))" "$ver_info"
195
196exit $failed
197