386 lines
9.1 KiB
Bash
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
|