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