armbian-build/extras-buildpkgs/FFmpeg/debian/tests/encdec
2016-07-09 00:18:41 +03:00

386 lines
9.1 KiB
Bash

#!/bin/bash
set -e
# test encoders and decoders
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
TEST_NAME="$1"
[ ! -z $TEST_NAME ] || TEST_NAME=${BASH_SOURCE[0]##*/}
ENCDECLIST="$SCRIPT_DIR/${TEST_NAME}"_list.txt
TEST_DIR="$ADTTMP/test"
encode_file() {
test=$1
dir=$2
mux=${test%%;*}
tenc=${test##*;}
type=${tenc%%=*}
enc=${tenc##*=}
codec=${enc%%:*}
encoder=${enc##*:}
file_name="$dir/$encoder.$mux"
opts=
# some codecs require extra options
if [ "$codec" == "avui" ]; then
opts="-s 720x486"
elif [ "$codec" == "dnxhd" ]; then
opts="-s 1280x720 -b:v 90M"
elif [ "$codec" == "dvvideo" ]; then
opts="-s 720x480 -pix_fmt yuv411p"
elif [ "$codec" == "h261" ]; then
opts="-s 176x144"
elif [ "$codec" == "h263" ]; then
opts="-s 128x96"
elif [ "$codec" == "hevc" ]; then
opts="-s 64x64"
elif [ "$codec" == "roq" ]; then
opts="-s 128x128"
elif [ "$codec" == "xface" ]; then
opts="-s 48x48"
elif [ "$codec" == "g723_1" ]; then
opts="-ar 8000 -b:a 6300"
elif [ "$codec" == "gsm" ]; then
opts="-ar 8000 -b:a 13000"
elif [ "$codec" == "gsm_ms" ]; then
opts="-ar 8000 -b:a 13000"
elif [ "$codec" == "roq_dpcm" ]; then
opts="-ar 22050"
elif [ "$codec" == "s302m" ]; then
opts="-ac 2"
elif [ "$codec" == "vorbis" ]; then
opts="-ac 2"
fi
src=
if [ "$type" = "v" ]; then
src=testsrc=s=32x32:d=0.1
elif [ "$type" = "a" ]; then
src=sine=d=0.1
else
# unknown codec type
return 10
fi
echo -e "trying muxer '$mux' with '$type' encoder '$encoder' for codec '$codec'\n"
ret=0
ffmpeg -f lavfi -i $src -strict -2 $opts -c:$type "$encoder" -f "$mux" "$file_name" -y -hide_banner 2>&1 || ret=$?
return $ret
}
probe_file() {
file_name=$1
test=$2
mux=${test%%;*}
tenc=${test##*;}
enc=${tenc##*=}
codec=${enc%%:*}
# determine the codec/format
ret=0
info=$(ffprobe -hide_banner -strict -2 "$file_name" 2>&1) || ret=$?
if [ "$ret" != 0 ]; then
echo "probing failed: $ret"
return "$ret"
fi
# file formats can be a comma-separated list, e.g. matroska,webm
file_formats=$(echo "$info" | grep "Input #" | sed "s/.*Input #[0-9]*, \([^ ]*\), from.*/\1/")
file_formats=${file_formats//,/ }
# there can be multiple streams, thus multiple codecs
file_codecs=$(echo "$info" | grep "Stream #" | sed "s/.*Stream #.*:.*:.*: \([^ ,]*\).*/\1/")
same_format=
same_codec=
# test if the file has the correct codec/format
for file_format in $file_formats; do
if [ "$mux" == "$file_format" ]; then
same_format="$file_format"
fi
done
if [ ! "$same_format" ]; then
# wrong format
echo "file has the wrong format: $file_formats"
return 10
fi
for file_codec in $file_codecs; do
if [ "$codec" == "$file_codec" ]; then
same_codec="$file_codec"
fi
done
if [ ! "$same_codec" ]; then
# wrong codec
echo "file has the wrong codec: $file_codecs"
return 11
fi
return 0
}
decode_file() {
file_name=$1
ret=0
# The option '-t 1' is necessary, because the comfortnoise decoder never stops producing noise.
ffmpeg -strict -2 -i "$file_name" -t 1 -c:v rawvideo -c:a pcm_s32le -f nut /dev/null -y -hide_banner 2>&1 || ret=$?
return $ret
}
list_formats() {
match="$1"
old_IFS=$IFS
# Set the field seperator to a newline
IFS="
"
# Get the raw list
lines=$(ffmpeg -hide_banner -formats | grep "^ $match")
for line in $lines; do
item=$(echo "$line" | sed "s/^ [D ][E ] \([^ ]*\) .*/\1/")
item=${item%%,*}
echo "$item"
done
IFS=$old_IFS
}
list_codecs() {
what=$1
match="$2"
type="$3"
old_IFS=$IFS
# Set the field seperator to a newline
IFS="
"
# Get the raw list
lines=$(ffmpeg -hide_banner -codecs | grep "^ $match$type")
for line in $lines; do
items=$(echo "$line" | grep "($what:")
codec=$(echo "$line" | sed "s/^ [^ ]* \([^ ]*\) .*/\1/")
if [ -z "$items" ]; then
echo "${type,,}=$codec"
else
# de/encoder(s) name(s) differ from codec name
items=$(echo "$items" | sed "s/.*($what: \([^)]*\) ).*/\1/")
IFS=" "
for item in $items; do
echo "${type,,}=$codec:$item"
done
IFS="
"
fi
done
IFS=$old_IFS
}
list_muxers() {
muxs=$(list_formats ".E [^=]")
echo $muxs
}
list_demuxers() {
dems=$(list_formats "D. [^=]")
echo $dems
}
list_video_encoders() {
vencs=$(list_codecs encoders ".E" "V")
echo $vencs
}
list_video_decoders() {
vdecs=$(list_codecs decoders "D." "V")
echo $vdecs
}
list_audio_encoders() {
aencs=$(list_codecs encoders ".E" "A")
echo $aencs
}
list_audio_decoders() {
adecs=$(list_codecs decoders "D." "A")
echo $adecs
}
read_tests() {
filename=$1
old_IFS=$IFS
# Set the field seperator to a newline
IFS="
"
# Get the raw list
lines=$(cat "$filename")
for line in $lines; do
muxer=${line%%;*}
tencs=${line##*;}
if [ "$tencs" ]; then
IFS=" "
for tenc in $tencs; do
echo "$muxer;$tenc"
done
IFS="
"
fi
done
IFS=$old_IFS
}
echo "TEST: $TEST_NAME"
echo -e "ADTTMP directory: $ADTTMP\n\n"
mkdir -p "$TEST_DIR"
ffmpeg -version 2>&1
echo -e "\n"
# determine the supported muxers and encoders
echo "muxers:"
muxs=$(list_muxers)
echo "$muxs"
echo -e "\n"
vencs=$(list_video_encoders)
aencs=$(list_audio_encoders)
echo "encoders:"
encs="$vencs $aencs"
echo "$encs"
echo -e "\n"
for mux in $muxs; do
mux_tests=
for tenc in $encs; do
mux_tests="$mux_tests $mux;$tenc "
done
possible_tests="$possible_tests$mux_tests"
done
if [ -f $ENCDECLIST ]; then
tests=$(read_tests $ENCDECLIST)
else
# create the list of working tests if it doesn't exist
update="true"
tests=$possible_tests
fi
num_tests=$(echo $tests | wc -w)
echo -e "$num_tests tests\n"
crashes=
failures=
skipped=
num_test=0
num_success=0
for test in $tests; do
num_test=$((num_test + 1))
echo "Test $num_test:"
# skip the test, if the muxer/encoder is not available
available=$(echo "$possible_tests" | grep " $test ") || true
if [ ! "$available" ]; then
skipped="${skipped}${test}\n"
echo -e "SKIPPED: $test\n\n"
continue
fi
mux=${test%%;*}
tenc=${test##*;}
ret=0
# try encoding a file
# this also sets the file_name variable
encode_file $test $TEST_DIR || ret=$?
echo -e "\n"
if [ "$ret" != "0" ]; then
errmsg="$test; encoding return code: $ret"
if [ "$ret" -gt 128 ]; then
crashes="${crashes}${errmsg}\n"
else
failures="${failures}${errmsg}\n"
fi
echo -e "FAILED: $errmsg\n\n"
continue
fi
ret=0
# test if the file has the correct format/codec
err=$(probe_file "$file_name" $test) || ret=$?
if [ "$ret" != "0" ]; then
errmsg="$test; $err"
if [ "$ret" -gt 128 ]; then
crashes="${crashes}${errmsg}\n"
else
failures="${failures}${errmsg}\n"
fi
echo -e "FAILED: $errmsg\n\n"
continue
fi
ret=0
# test decoding the file
decode_file "$file_name" || ret=$?
if [ "$ret" != "0" ]; then
errmsg="$test; decoding return code: $ret"
if [ "$ret" -gt 128 ]; then
crashes="${crashes}${errmsg}\n"
else
failures="${failures}${errmsg}\n"
fi
echo -e "FAILED: $errmsg\n\n"
continue
fi
echo -e "\nSUCCESS: correctly created file with format '$mux' and codec '$tenc'\n\n"
num_success=$((num_success + 1))
if [ "$update" ]; then
if [ "x$last_mux" != "x$mux" ]; then
if [ "$last_mux" ]; then
# newline
echo "" >> $ENCDECLIST
fi
echo -n "$mux;" >> $ENCDECLIST
fi
last_mux=$mux
echo -n " $tenc" >> $ENCDECLIST
fi
done
echo "done!"
ret=0
num_crashes=0
num_failures=0
num_skipped=0
if [ "$crashes" ]; then
num_crashes=$(echo -e "$crashes" | wc -l)
num_crashes=$((num_crashes - 1))
fi
if [ "$failures" ]; then
num_failures=$(echo -e "$failures" | wc -l)
num_failures=$((num_failures - 1))
fi
if [ "$skipped" ]; then
num_skipped=$(echo -e "$skipped" | wc -l)
num_skipped=$((num_skipped - 1))
fi
if [ "$num_crashes" != "0" ]; then
ret=1
echo -e "\n\ncrashes: $num_crashes\n"
echo -e "$crashes"
fi
if [ "$num_failures" != "0" ]; then
ret=1
echo -e "\n\nfailures: $num_failures\n"
echo -e "$failures"
fi
if [ "$num_skipped" != "0" ]; then
echo -e "\n\nskipped: $num_skipped\n"
echo -e "$skipped"
fi
if [ "$num_success" != "0" ]; then
echo -e "\n\nsuccess: $num_success\n"
else
ret=1
echo -e "\n\nno single success: something is definitely wrong\n"
fi
exit $ret