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