• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /bin/sh
2
3export LC_ALL=C
4
5base=$(dirname $0)
6. "${base}/md5.sh"
7
8base64=tests/base64${HOSTEXECSUF}
9
10test="${1#fate-}"
11target_samples=$2
12target_exec=$3
13target_path=$4
14command=$5
15cmp=${6:-diff}
16ref=${7:-"${base}/ref/fate/${test}"}
17fuzz=${8:-1}
18threads=${9:-1}
19thread_type=${10:-frame+slice}
20cpuflags=${11:-all}
21cmp_shift=${12:-0}
22cmp_target=${13:-0}
23size_tolerance=${14:-0}
24cmp_unit=${15:-2}
25gen=${16:-no}
26hwaccel=${17:-none}
27report_type=${18:-standard}
28keep=${19:-0}
29
30outdir="tests/data/fate"
31outfile="${outdir}/${test}"
32errfile="${outdir}/${test}.err"
33cmpfile="${outdir}/${test}.diff"
34repfile="${outdir}/${test}.rep"
35
36target_path(){
37    test ${1} = ${1#/} && p=${target_path}/
38    echo ${p}${1}
39}
40
41# $1=value1, $2=value2, $3=threshold
42# prints 0 if absolute difference between value1 and value2 is <= threshold
43compare(){
44    awk "BEGIN { v = $1 - $2; printf ((v < 0 ? -v : v) > $3) }"
45}
46
47do_tiny_psnr(){
48    psnr=$(tests/tiny_psnr${HOSTEXECSUF} "$1" "$2" $cmp_unit $cmp_shift 0) || return 1
49    val=$(expr "$psnr" : ".*$3: *\([0-9.]*\)")
50    size1=$(expr "$psnr" : '.*bytes: *\([0-9]*\)')
51    size2=$(expr "$psnr" : '.*bytes:[ 0-9]*/ *\([0-9]*\)')
52    val_cmp=$(compare $val $cmp_target $fuzz)
53    size_cmp=$(compare $size1 $size2 $size_tolerance)
54    if [ "$val_cmp" != 0 ] || [ "$size_cmp" != 0 ]; then
55        echo "$psnr"
56        if [ "$val_cmp" != 0 ]; then
57            echo "$3: |$val - $cmp_target| >= $fuzz"
58        fi
59        if [ "$size_cmp" != 0 ]; then
60            echo "size: |$size1 - $size2| >= $size_tolerance"
61        fi
62        return 1
63    fi
64}
65
66oneoff(){
67    do_tiny_psnr "$1" "$2" MAXDIFF
68}
69
70stddev(){
71    do_tiny_psnr "$1" "$2" stddev
72}
73
74oneline(){
75    printf '%s\n' "$1" | diff -u -b - "$2"
76}
77
78run(){
79    test "${V:-0}" -gt 0 && echo "$target_exec" $target_path/"$@" >&3
80    $target_exec $target_path/"$@"
81}
82
83runecho(){
84    test "${V:-0}" -gt 0 && echo "$target_exec" $target_path/"$@" >&3
85    $target_exec $target_path/"$@" >&3
86}
87
88probefmt(){
89    run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_entries format=format_name -print_format default=nw=1:nk=1 "$@"
90}
91
92probeaudiostream(){
93    run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_entries stream=codec_name,codec_time_base,sample_fmt,channels,channel_layout:side_data "$@"
94}
95
96probetags(){
97    run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_entries format_tags "$@"
98}
99
100runlocal(){
101    test "${V:-0}" -gt 0 && echo ${base}/"$@" ${base} >&3
102    ${base}/"$@" ${base}
103}
104
105probeframes(){
106    run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_frames "$@"
107}
108
109probechapters(){
110    run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_chapters "$@"
111}
112
113probegaplessinfo(){
114    filename="$1"
115    shift
116    run ffprobe${PROGSUF}${EXECSUF} -bitexact -select_streams a -show_entries format=start_time,duration:stream=index,start_pts,duration_ts "$filename" "$@"
117    pktfile1="${outdir}/${test}.pkts"
118    framefile1="${outdir}/${test}.frames"
119    cleanfiles="$cleanfiles $pktfile1 $framefile1"
120    run ffprobe${PROGSUF}${EXECSUF} -bitexact -select_streams a -of compact -count_packets -show_entries packet=pts,dts,duration,flags:stream=nb_read_packets "$filename" "$@" > "$pktfile1"
121    head -n 8 "$pktfile1"
122    tail -n 9 "$pktfile1"
123    run ffprobe${PROGSUF}${EXECSUF} -bitexact -select_streams a -of compact -count_frames -show_entries frame=pts,pkt_dts,best_effort_timestamp,pkt_duration,nb_samples:stream=nb_read_frames "$filename" "$@" > "$framefile1"
124    head -n 8 "$framefile1"
125    tail -n 9 "$framefile1"
126}
127
128ffmpeg(){
129    dec_opts="-hwaccel $hwaccel -threads $threads -thread_type $thread_type"
130    ffmpeg_args="-nostdin -nostats -noauto_conversion_filters -cpuflags $cpuflags"
131    for arg in $@; do
132        [ x${arg} = x-i ] && ffmpeg_args="${ffmpeg_args} ${dec_opts}"
133        ffmpeg_args="${ffmpeg_args} ${arg}"
134    done
135    run ffmpeg${PROGSUF}${EXECSUF} ${ffmpeg_args}
136}
137
138ffprobe_demux(){
139    filename=$1
140    shift
141    print_filename=$(basename "$filename")
142    run ffprobe${PROGSUF}${EXECSUF} -print_filename "${print_filename}" \
143        -of compact -bitexact -show_format -show_streams -show_packets  \
144        -show_data_hash CRC32 "$filename" "$@"
145}
146
147framecrc(){
148    ffmpeg "$@" -bitexact -f framecrc -
149}
150
151ffmetadata(){
152    ffmpeg "$@" -bitexact -f ffmetadata -
153}
154
155framemd5(){
156    ffmpeg "$@" -bitexact -f framemd5 -
157}
158
159crc(){
160    ffmpeg "$@" -f crc -
161}
162
163md5pipe(){
164    ffmpeg "$@" md5:
165}
166
167md5(){
168    encfile="${outdir}/${test}.out"
169    cleanfiles="$cleanfiles $encfile"
170    ffmpeg -y "$@" $(target_path $encfile) || return
171    do_md5sum $encfile | awk '{print $1}'
172}
173
174pcm(){
175    ffmpeg -auto_conversion_filters "$@" -vn -f s16le -
176}
177
178fmtstdout(){
179    fmt=$1
180    shift 1
181    ffmpeg -bitexact "$@" -bitexact -f $fmt -
182}
183
184enc_dec_pcm(){
185    out_fmt=$1
186    dec_fmt=$2
187    pcm_fmt=$3
188    src_file=$(target_path $4)
189    shift 4
190    encfile="${outdir}/${test}.${out_fmt}"
191    cleanfiles=$encfile
192    encfile=$(target_path ${encfile})
193    ffmpeg -auto_conversion_filters -i $src_file "$@" -f $out_fmt -y ${encfile} || return
194    ffmpeg -auto_conversion_filters -bitexact -i ${encfile} -c:a pcm_${pcm_fmt} -fflags +bitexact -f ${dec_fmt} -
195}
196
197FLAGS="-flags +bitexact -sws_flags +accurate_rnd+bitexact -fflags +bitexact"
198DEC_OPTS="-threads $threads -thread_type $thread_type -idct simple $FLAGS"
199ENC_OPTS="-threads 1        -idct simple -dct fastint"
200
201enc_dec(){
202    enc_fmt_in=$1
203    srcfile=$2
204    enc_fmt_out=$3
205    enc_opt_out=$4
206    dec_fmt_out=$5
207    dec_opt_out=$6
208    dec_opt_in=$7
209    ffprobe_opts=$8
210    twopass=$9
211    encfile="${outdir}/${test}.${enc_fmt_out}"
212    decfile="${outdir}/${test}.out.${dec_fmt_out}"
213    cleanfiles="$cleanfiles $decfile"
214    test "$keep" -ge 1 || cleanfiles="$cleanfiles $encfile"
215    tsrcfile=$(target_path $srcfile)
216    tencfile=$(target_path $encfile)
217    tdecfile=$(target_path $decfile)
218
219    if [ -n "$twopass" ]; then
220        logfile_prefix="${outdir}/${test}.pass1"
221        cleanfiles="$cleanfiles ${logfile_prefix}-0.log"
222        tlogfile_prefix=$(target_path $logfile_prefix)
223        ffmpeg -auto_conversion_filters -f $enc_fmt_in $DEC_OPTS -i $tsrcfile  \
224            $ENC_OPTS $enc_opt_out $FLAGS -pass 1 -passlogfile $tlogfile_prefix \
225            -f $enc_fmt_out -y $tencfile || return
226        enc_opt_out="$enc_opt_out -pass 2 -passlogfile $tlogfile_prefix"
227    fi
228
229    ffmpeg -auto_conversion_filters -f $enc_fmt_in $DEC_OPTS -i $tsrcfile $ENC_OPTS $enc_opt_out $FLAGS \
230        -f $enc_fmt_out -y $tencfile || return
231    do_md5sum $encfile
232    echo $(wc -c $encfile)
233    ffmpeg -auto_conversion_filters $dec_opt_in $DEC_OPTS -i $tencfile $ENC_OPTS $dec_opt_out $FLAGS \
234        -f $dec_fmt_out -y $tdecfile || return
235    do_md5sum $decfile
236    tests/tiny_psnr${HOSTEXECSUF} $srcfile $decfile $cmp_unit $cmp_shift
237    test -z $ffprobe_opts || \
238        run ffprobe${PROGSUF}${EXECSUF} -bitexact $ffprobe_opts $tencfile || return
239}
240
241transcode(){
242    src_fmt=$1
243    srcfile=$2
244    enc_fmt=$3
245    enc_opt=$4
246    final_encode=$5
247    ffprobe_opts=$6
248    additional_input=$7
249    final_decode=$8
250    test -z "$additional_input" || additional_input="$DEC_OPTS $additional_input"
251    encfile="${outdir}/${test}.${enc_fmt}"
252    test $keep -ge 1 || cleanfiles="$cleanfiles $encfile"
253    tsrcfile=$(target_path $srcfile)
254    tencfile=$(target_path $encfile)
255    ffmpeg -f $src_fmt $DEC_OPTS -i $tsrcfile $additional_input \
256           $ENC_OPTS $enc_opt $FLAGS -f $enc_fmt -y $tencfile || return
257    do_md5sum $encfile
258    echo $(wc -c $encfile)
259    ffmpeg $DEC_OPTS $final_decode -i $tencfile $ENC_OPTS $FLAGS $final_encode \
260        -f framecrc - || return
261    test -z $ffprobe_opts || \
262        run ffprobe${PROGSUF}${EXECSUF} -bitexact $ffprobe_opts $tencfile || return
263}
264
265stream_remux(){
266    src_fmt=$1
267    srcfile=$2
268    enc_fmt=$3
269    stream_maps=$4
270    final_decode=$5
271    ffprobe_opts=$6
272    encfile="${outdir}/${test}.${enc_fmt}"
273    test $keep -ge 1 || cleanfiles="$cleanfiles $encfile"
274    tsrcfile=$(target_path $srcfile)
275    tencfile=$(target_path $encfile)
276    ffmpeg -f $src_fmt -i $tsrcfile $stream_maps -codec copy $FLAGS \
277        -f $enc_fmt -y $tencfile || return
278    ffmpeg $DEC_OPTS -i $tencfile $ENC_OPTS $FLAGS $final_decode \
279        -f framecrc - || return
280    test -z $ffprobe_opts || \
281        run ffprobe${PROGSUF}${EXECSUF} -bitexact $ffprobe_opts $tencfile || return
282}
283
284# FIXME: There is a certain duplication between the avconv-related helper
285# functions above and below that should be refactored.
286ffmpeg2="$target_exec ${target_path}/ffmpeg${PROGSUF}${EXECSUF}"
287raw_src="${target_path}/tests/vsynth1/%02d.pgm"
288pcm_src="${target_path}/tests/data/asynth1.sw"
289
290[ "${V-0}" -gt 0 ] && echov=echov || echov=:
291
292echov(){
293    echo "$@" >&3
294}
295
296AVCONV_OPTS="-nostdin -nostats -noauto_conversion_filters -y -cpuflags $cpuflags -filter_threads $threads"
297COMMON_OPTS="-flags +bitexact -idct simple -sws_flags +accurate_rnd+bitexact -fflags +bitexact"
298DEC_OPTS="$COMMON_OPTS -threads $threads"
299ENC_OPTS="$COMMON_OPTS -threads 1 -dct fastint"
300
301run_avconv(){
302    $echov $ffmpeg2 $AVCONV_OPTS $*
303    $ffmpeg2 $AVCONV_OPTS $*
304}
305
306do_avconv(){
307    f="$1"
308    shift
309    set -- $* ${target_path}/$f
310    run_avconv $*
311    do_md5sum $f
312    echo $(wc -c $f)
313}
314
315do_avconv_crc(){
316    f="$1"
317    shift
318    printf "%s " "$f"
319    run_avconv $* -f crc -
320}
321
322lavf_audio(){
323    t="${test#lavf-}"
324    outdir="tests/data/lavf"
325    file=${outdir}/lavf.$t
326    test "$keep" -ge 1 || cleanfiles="$cleanfiles $file"
327    do_avconv $file -auto_conversion_filters $DEC_OPTS $1 -ar 44100 -f s16le -i $pcm_src "$ENC_OPTS -metadata title=lavftest" -t 1 -qscale 10 $2
328    test "$4" = "disable_crc" ||
329        do_avconv_crc $file -auto_conversion_filters $DEC_OPTS $3 -i $target_path/$file
330}
331
332lavf_container(){
333    t="${test#lavf-}"
334    outdir="tests/data/lavf"
335    file=${outdir}/lavf.$t
336    test "$keep" -ge 1 || cleanfiles="$cleanfiles $file"
337    do_avconv $file -auto_conversion_filters $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le $1 -i $pcm_src "$ENC_OPTS -metadata title=lavftest" -b:a 64k -t 1 -qscale:v 10 $2
338    test "$3" = "disable_crc" ||
339        do_avconv_crc $file -auto_conversion_filters $DEC_OPTS -i $target_path/$file $3
340}
341
342lavf_container_attach() {          lavf_container "" "$1 -attach ${raw_src%/*}/00.pgm -metadata:s:t mimetype=image/x-portable-greymap"; }
343lavf_container_timecode_nodrop() { lavf_container "" "$1 -timecode 02:56:14:13"; }
344lavf_container_timecode_drop()   { lavf_container "" "$1 -timecode 02:56:14.13 -r 30000/1001"; }
345
346lavf_container_timecode()
347{
348    lavf_container_timecode_nodrop "$@"
349    lavf_container_timecode_drop "$@"
350    lavf_container "" "$1"
351}
352
353lavf_container_fate()
354{
355    t="${test#lavf-fate-}"
356    outdir="tests/data/lavf-fate"
357    file=${outdir}/lavf.$t
358    cleanfiles="$cleanfiles $file"
359    input="${target_samples}/$1"
360    do_avconv $file -auto_conversion_filters $DEC_OPTS $2 -i "$input" "$ENC_OPTS -metadata title=lavftest" -vcodec copy -acodec copy
361    do_avconv_crc $file -auto_conversion_filters $DEC_OPTS -i $target_path/$file $3
362}
363
364lavf_image(){
365    no_file_checksums="$3"
366    nb_frames=13
367    t="${test#lavf-}"
368    outdir="tests/data/images/$t"
369    mkdir -p "$outdir"
370    file=${outdir}/%02d.$t
371    if [ "$keep" -lt 1 ]; then
372        for i in `seq $nb_frames`; do
373            filename=`printf "$file" $i`
374            cleanfiles="$cleanfiles $filename"
375        done
376    fi
377    run_avconv $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src $1 "$ENC_OPTS -metadata title=lavftest" -vf scale -frames $nb_frames -y -qscale 10 $target_path/$file
378    if [ -z "$no_file_checksums" ]; then
379        do_md5sum ${outdir}/02.$t
380        echo $(wc -c ${outdir}/02.$t)
381    fi
382    do_avconv_crc $file -auto_conversion_filters $DEC_OPTS $2 -i $target_path/$file $2
383}
384
385lavf_image2pipe(){
386    t="${test#lavf-}"
387    t="${t%pipe}"
388    outdir="tests/data/lavf"
389    file=${outdir}/${t}pipe.$t
390    do_avconv $file -auto_conversion_filters $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src -f image2pipe "$ENC_OPTS -metadata title=lavftest" -t 1 -qscale 10
391    do_avconv_crc $file -auto_conversion_filters $DEC_OPTS -f image2pipe -i $target_path/$file
392}
393
394lavf_video(){
395    t="${test#lavf-}"
396    outdir="tests/data/lavf"
397    file=${outdir}/lavf.$t
398    test "$keep" -ge 1 || cleanfiles="$cleanfiles $file"
399    do_avconv $file -auto_conversion_filters $DEC_OPTS -f image2 -c:v pgmyuv -i $raw_src "$ENC_OPTS -metadata title=lavftest" -t 1 -qscale 10 $1 $2
400    do_avconv_crc $file -auto_conversion_filters $DEC_OPTS -i $target_path/$file $1
401}
402
403refcmp_metadata(){
404    refcmp=$1
405    pixfmt=$2
406    fuzz=${3:-0.001}
407    ffmpeg -auto_conversion_filters $FLAGS $ENC_OPTS \
408        -lavfi "testsrc2=size=300x200:rate=1:duration=5,format=${pixfmt},split[ref][tmp];[tmp]avgblur=4[enc];[enc][ref]${refcmp},metadata=print:file=-" \
409        -f null /dev/null | awk -v ref=${ref} -v fuzz=${fuzz} -f ${base}/refcmp-metadata.awk -
410}
411
412cmp_metadata(){
413    refcmp=$1
414    pixfmt=$2
415    fuzz=${3:-0.001}
416    ffmpeg $FLAGS $ENC_OPTS \
417        -lavfi "testsrc2=size=300x200:rate=1:duration=5,format=${pixfmt},${refcmp},metadata=print:file=-" \
418        -f null /dev/null | awk -v ref=${ref} -v fuzz=${fuzz} -f ${base}/refcmp-metadata.awk -
419}
420
421refcmp_metadata_files(){
422    file1=$1
423    file2=$2
424    refcmp=$3
425    pixfmt=$4
426    fuzz=${5:-0.001}
427    ffmpeg -auto_conversion_filters $FLAGS -i $file1 $FLAGS -i $file2 $ENC_OPTS \
428        -lavfi "[0:v]format=${pixfmt}[v0];[1:v]format=${pixfmt}[v1];[v0][v1]${refcmp},metadata=print:file=-" \
429        -f null /dev/null | awk -v ref=${ref} -v fuzz=${fuzz} -f ${base}/refcmp-metadata.awk -
430}
431
432refcmp_metadata_transcode(){
433    srcfile=$1
434    enc_opt=$2
435    enc_fmt=$3
436    enc_ext=$4
437    shift 4
438    encfile="${outdir}/${test}.${enc_ext}"
439    cleanfiles="$cleanfiles $encfile"
440    tsrcfile=$(target_path $srcfile)
441    tencfile=$(target_path $encfile)
442    ffmpeg $DEC_OPTS -i $tsrcfile $ENC_OPTS $enc_opt $FLAGS -y -f $enc_fmt $tencfile || return
443    refcmp_metadata_files $tencfile $tsrcfile "$@"
444}
445
446pixfmt_conversion(){
447    conversion="${test#pixfmt-}"
448    outdir="tests/data/pixfmt"
449    raw_dst="$outdir/$conversion.out.yuv"
450    file=${outdir}/${conversion}.yuv
451    cleanfiles="$cleanfiles $raw_dst $file"
452    run_avconv $DEC_OPTS -r 1 -f image2 -c:v pgmyuv -i $raw_src \
453               $ENC_OPTS -f rawvideo -t 1 -s 352x288 -pix_fmt $conversion $target_path/$raw_dst
454    do_avconv $file $DEC_OPTS -f rawvideo -s 352x288 -pix_fmt $conversion -i $target_path/$raw_dst \
455              $ENC_OPTS -f rawvideo -s 352x288 -pix_fmt yuv444p
456}
457
458video_filter(){
459    filters=$1
460    shift
461    label=${test#filter-}
462    raw_src="${target_path}/tests/vsynth1/%02d.pgm"
463    printf '%-20s' $label
464    ffmpeg $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src \
465        $FLAGS $ENC_OPTS -vf "$filters" -vcodec rawvideo -frames:v 5 $* -f nut md5:
466}
467
468pixfmts(){
469    filter=${test#filter-pixfmts-}
470    filter=${filter%_*}
471    filter_args=$1
472    prefilter_chain=$2
473    nframes=${3:-1}
474
475    showfiltfmts="$target_exec $target_path/libavfilter/tests/filtfmts${EXECSUF}"
476    scale_exclude_fmts=${outfile}_scale_exclude_fmts
477    scale_in_fmts=${outfile}_scale_in_fmts
478    scale_out_fmts=${outfile}_scale_out_fmts
479    in_fmts=${outfile}_in_fmts
480
481    # exclude pixel formats which are not supported as input
482    $showfiltfmts scale | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort >$scale_in_fmts
483    $showfiltfmts scale | awk -F '[ \r]' '/^OUTPUT/{ fmt=substr($3, 5); print fmt }' | sort >$scale_out_fmts
484    comm -12 $scale_in_fmts $scale_out_fmts >$scale_exclude_fmts
485
486    $showfiltfmts $filter | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort >$in_fmts
487    pix_fmts=$(comm -12 $scale_exclude_fmts $in_fmts)
488
489    outertest=$test
490    for pix_fmt in $pix_fmts; do
491        test=$pix_fmt
492        video_filter "${prefilter_chain}scale,format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt -frames:v $nframes
493    done
494
495    rm $in_fmts $scale_in_fmts $scale_out_fmts $scale_exclude_fmts
496    test=$outertest
497}
498
499gapless(){
500    sample=$(target_path $1)
501    extra_args=$2
502
503    decfile1="${outdir}/${test}.out-1"
504    decfile2="${outdir}/${test}.out-2"
505    decfile3="${outdir}/${test}.out-3"
506    cleanfiles="$cleanfiles $decfile1 $decfile2 $decfile3"
507
508    # test packet data
509    ffmpeg -auto_conversion_filters $extra_args -i "$sample" -bitexact -c:a copy -f framecrc -y $(target_path $decfile1)
510    do_md5sum $decfile1
511    # test decoded (and cut) data
512    ffmpeg -auto_conversion_filters $extra_args -i "$sample" -bitexact -f wav md5:
513    # the same as above again, with seeking to the start
514    ffmpeg -auto_conversion_filters $extra_args -ss 0 -seek_timestamp 1 -i "$sample" -bitexact -c:a copy -f framecrc -y $(target_path $decfile2)
515    do_md5sum $decfile2
516    ffmpeg -auto_conversion_filters $extra_args -ss 0 -seek_timestamp 1 -i "$sample" -bitexact -f wav md5:
517    # test packet data, with seeking to a specific position
518    ffmpeg -auto_conversion_filters $extra_args -ss 5 -seek_timestamp 1 -i "$sample" -bitexact -c:a copy -f framecrc -y $(target_path $decfile3)
519    do_md5sum $decfile3
520}
521
522gaplessenc(){
523    sample=$(target_path $1)
524    format=$2
525    codec=$3
526
527    file1="${outdir}/${test}.out-1"
528    cleanfiles="$cleanfiles $file1"
529
530    # test data after reencoding
531    ffmpeg -i "$sample" -bitexact -map 0:a -c:a $codec -af aresample -f $format -y "$(target_path "$file1")"
532    probegaplessinfo "$(target_path "$file1")"
533}
534
535audio_match(){
536    sample=$(target_path $1)
537    trefile=$2
538    extra_args=$3
539
540    decfile="${outdir}/${test}.wav"
541    cleanfiles="$cleanfiles $decfile"
542
543    ffmpeg -auto_conversion_filters -i "$sample" -bitexact $extra_args -y $(target_path $decfile)
544    tests/audiomatch${HOSTEXECSUF} $decfile $trefile
545}
546
547concat(){
548    template=$1
549    sample=$2
550    mode=$3
551    extra_args=$4
552
553    concatfile="${outdir}/${test}.ffconcat"
554    packetfile="${outdir}/${test}.ffprobe"
555    cleanfiles="$concatfile $packetfile"
556
557    awk "{gsub(/%SRCFILE%/, \"$sample\"); print}" $template > $concatfile
558
559    if [ "$mode" = "md5" ]; then
560        run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_streams -show_packets -safe 0 $extra_args $(target_path $concatfile) | tr -d '\r' > $packetfile
561        do_md5sum $packetfile
562    else
563        run ffprobe${PROGSUF}${EXECSUF} -bitexact -show_streams -show_packets -of compact=p=0:nk=1 -safe 0 $extra_args $(target_path $concatfile)
564    fi
565}
566
567venc_data(){
568    file=$1
569    stream=$2
570    frames=$3
571    run tools/venc_data_dump${EXECSUF} ${file} ${stream} ${frames} ${threads} ${thread_type}
572}
573
574null(){
575    :
576}
577
578# Disable globbing: command arguments may contain globbing characters and
579# must be kept verbatim
580set -f
581
582exec 3>&2
583eval $command >"$outfile" 2>$errfile
584err=$?
585
586if [ $err -gt 128 ]; then
587    sig=$(kill -l $err 2>/dev/null)
588    test "${sig}" = "${sig%[!A-Za-z]*}" || unset sig
589fi
590
591if test -e "$ref" || test $cmp = "oneline" || test $cmp = "null" || test $cmp = "grep" ; then
592    case $cmp in
593        diff)   diff -u -b "$ref" "$outfile"            >$cmpfile ;;
594        rawdiff)diff -u    "$ref" "$outfile"            >$cmpfile ;;
595        oneoff) oneoff     "$ref" "$outfile"            >$cmpfile ;;
596        stddev) stddev     "$ref" "$outfile"            >$cmpfile ;;
597        oneline)oneline    "$ref" "$outfile"            >$cmpfile ;;
598        grep)   grep       "$ref" "$errfile"            >$cmpfile ;;
599        null)   cat               "$outfile"            >$cmpfile ;;
600    esac
601    cmperr=$?
602    test $err = 0 && err=$cmperr
603    if [ "$report_type" = "ignore" ]; then
604        test $err = 0 || echo "IGNORE\t${test}" && err=0 && unset sig
605    else
606        test $err = 0 || cat $cmpfile
607    fi
608else
609    echo "reference file '$ref' not found"
610    err=1
611fi
612
613if [ $err -eq 0 ] && test $report_type = "standard" ; then
614    unset cmpo erro
615else
616    cmpo="$($base64 <$cmpfile)"
617    erro="$($base64 <$errfile)"
618fi
619echo "${test}:${sig:-$err}:$cmpo:$erro" >$repfile
620
621if test $err != 0 && test $gen != "no" ; then
622    echo "GEN     $ref"
623    cp -f "$outfile" "$ref"
624    err=$?
625fi
626
627if test $err = 0; then
628    if test $keep -lt 2; then
629        rm -f $outfile $errfile $cmpfile $cleanfiles
630    fi
631elif test $gen = "no"; then
632    echo "Test $test failed. Look at $errfile for details."
633    test "${V:-0}" -gt 0 && cat $errfile
634else
635    echo "Updating reference failed, possibly no output file was generated."
636fi
637exit $err
638