diff options
| author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2016-05-16 21:55:52 +0300 | 
|---|---|---|
| committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2016-05-19 16:55:07 +0300 | 
| commit | 62f0b16f639a9ecb116a79819655bdf44e269443 (patch) | |
| tree | f66dc07c616b3f387f3ec941537e840fce261322 /scripts | |
Initial commit
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/Makefile | 8 | ||||
| -rwxr-xr-x | scripts/histo2png.py | 81 | ||||
| -rwxr-xr-x | scripts/logger.sh | 11 | ||||
| -rwxr-xr-x | scripts/vsp-lib.sh | 441 | ||||
| -rwxr-xr-x | scripts/vsp-runner.sh | 135 | 
5 files changed, 676 insertions, 0 deletions
diff --git a/scripts/Makefile b/scripts/Makefile new file mode 100644 index 0000000..27bac1a --- /dev/null +++ b/scripts/Makefile @@ -0,0 +1,8 @@ +SCRIPTS=logger.sh vsp-lib.sh vsp1.sh + +all: + +clean: + +install: +	cp $(SCRIPTS) $(INSTALL_DIR)/ diff --git a/scripts/histo2png.py b/scripts/histo2png.py new file mode 100755 index 0000000..ff1da21 --- /dev/null +++ b/scripts/histo2png.py @@ -0,0 +1,81 @@ +#!/usr/bin/python + +import matplotlib.pyplot as plt +import struct +import sys + + +def usage(argv0): +	print 'Usage: %s <histo.bin>' % argv0 + + +def main(argv): + +	if len(argv) != 2: +		usage(argv[0]) +		return 1 + +	data = file(argv[1], 'rb').read() + +	if len(data) == (2 + 64) * 4 or len(data) == (2 + 256) * 4: +		maxmin = struct.unpack('<I', data[0:4]) +		sums = struct.unpack('<I', data[4:8]) +		histo = struct.unpack('<%uI' % (len(data[8:]) / 4), data[8:]) + +		num_bins = len(histo); + +		title = 'min %u max %u sum %u' % \ +			((maxmin[0] >>  0) & 0xff, (maxmin[0] >> 16) & 0xff, sums[0]) + +		print 'pixels (%u)' % sum(histo) + +		plt.figure(figsize=(10, 10)) +		plt.xlim([0, num_bins]) +		plt.ylim([0, max(histo)]) +		plt.bar(range(num_bins), histo, color='r'); + +	elif len(data) == (6 + 64 * 3) * 4: +		maxmin = struct.unpack('<III', data[0:12]) +		sums = struct.unpack('<III', data[12:24]) +		histo = [struct.unpack('<I', data[24+i*4:24+i*4+4])[0] for i in xrange(len(data[24:])/4)] + +		num_bins = len(histo) / 3; + +		histo_r = histo[0:num_bins] +		histo_g = histo[num_bins:2*num_bins] +		histo_b = histo[num_bins*2:] + +		title = 'RGB min (%u,%u,%u) max (%u,%u,%u) sum (%u,%u,%u)' % \ +			((maxmin[0] >>  0) & 0xff, (maxmin[1] >>  0) & 0xff, (maxmin[2] >>  0) & 0xff, +			 (maxmin[0] >> 16) & 0xff, (maxmin[1] >> 16) & 0xff, (maxmin[2] >> 16) & 0xff, +			 sums[0], sums[1], sums[2]) + +		print 'pixels RGB (%u,%u,%u)' % (sum(histo_r), sum(histo_g), sum(histo_b)) + +		plt.figure(figsize=(10, 20)) +		plt.subplot(3, 1, 1) +		plt.xlim([0, num_bins]) +		plt.ylim([0, max(histo_r)]) +		plt.bar(range(num_bins), histo_r, color='r'); +		plt.subplot(3, 1, 2) +		plt.xlim([0, num_bins]) +		plt.ylim([0, max(histo_g)]) +		plt.bar(range(num_bins), histo_g, color='g'); +		plt.subplot(3, 1, 3) +		plt.xlim([0, num_bins]) +		plt.ylim([0, max(histo_b)]) +		plt.bar(range(num_bins), histo_b, color='b'); + +	else: +		print 'Invalid histogram length %u' % len(data) +		return 1 + +	plt.suptitle(title) +	plt.savefig(argv[1].replace('bin', 'png'), dpi=72) + +        return 0 + + +if __name__ == '__main__': +        sys.exit(main(sys.argv)) + diff --git a/scripts/logger.sh b/scripts/logger.sh new file mode 100755 index 0000000..8123f0c --- /dev/null +++ b/scripts/logger.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +now() { +	awk '/^now/ {time=$3; printf("[%u.%06u]", time / 1000000000, (time % 1000000000) / 1000) ; exit}' /proc/timer_list +} + +label=${1:+ [$1]} + +while read line ; do +	echo "$(now)$label $line" +done diff --git a/scripts/vsp-lib.sh b/scripts/vsp-lib.sh new file mode 100755 index 0000000..4d3d166 --- /dev/null +++ b/scripts/vsp-lib.sh @@ -0,0 +1,441 @@ +#!/bin/sh + +mediactl='media-ctl' +yavta='yavta' + +# ------------------------------------------------------------------------------ +# Miscellaneous +# + +vsp1_device() { +	$mediactl -d $mdev -p | grep 'bus info' | sed 's/.*platform://' +} + +vsp1_has_feature() { +	feature=$1 + +	$mediactl -d $mdev -p | grep -q -- "- entity.*$feature" +} + +vsp1_count_rpfs() { +	$mediactl -d $mdev -p | grep -- '- entity.*rpf.[0-9] [^i]' | wc -l +} + +vsp1_count_wpfs() { +	$mediactl -d $mdev -p | grep -- '- entity.*wpf.[0-9] [^o]' | wc -l +} + +vsp1_count_bru_inputs() { +	num_pads=`media-ctl -p | grep 'entity.*bru' | sed 's/.*(\([0-9]\) pads.*/\1/'` +	echo $((num_pads-1)) +} + +vsp1_entity_get_size() { +	entity=$1 +	pad=$2 + +	$mediactl -d $mdev --get-v4l2 "'$dev $entity':$pad" | grep fmt | \ +	      sed 's/.*\/\([0-9x]*\).*/\1/' +} + +# ------------------------------------------------------------------------------ +# Image and histogram comparison +# + +# +# Compare the two frames for exact match. +# +compare_frame_exact() { +	img_a=$3 +	img_b=$4 + +	match='fail' +	diff -q $img_a $img_b > /dev/null && match='pass' + +	echo "Compared $img_a and $img_b: $match" | ./logger.sh check >> $logfile + +	if [ $match = 'pass' ] ; then +		return 0 +	else +		return 1 +	fi +} + +# +# Compare the two frames using a fuzzy match algorithm to account for errors +# introduced by the YUV packing. Accept a maximum 1% mean average error over +# the whole frame with no more than 5% of the pixels differing. +# +compare_frame_fuzzy() { +	fmt=$(echo $1 | sed 's/M$//') +	size=$2 +	img_a=$3 +	img_b=$4 + +	png_a=${img_a/bin/png} +	png_b=${img_b/bin/png} + +	raw2rgbpnm -f $fmt -s $size $img_a $png_a > /dev/null +	raw2rgbpnm -f $fmt -s $size $img_b $png_b > /dev/null + +	ae=$(compare -metric ae $png_a $png_b /dev/null 2>&1) +	mae=$(compare -metric mae $png_a $png_b /dev/null 2>&1 | sed 's/.*(\(.*\))/\1/') + +	rm $png_a +	rm $png_b + +	width=$(echo $size | cut -d 'x' -f 1) +	height=$(echo $size | cut -d 'x' -f 2) + +	ae_match=$(echo $ae $width $height | awk '{ if ($1 / $2 / $3 < 0.05) { print "pass" } else { print "fail" } }') +	mae_match=$(echo $mae | awk '{ if ($1 < 0.01) { print "pass" } else { print "fail" } }') + +	echo "Compared $img_a and $img_b: ae $ae ($ae_match) mae $mae ($mae_match)" | ./logger.sh check >> $logfile + +	if [ $ae_match = 'pass' -a $mae_match = 'pass' ] ; then +		return 0 +	else +		return 1 +	fi +} + +compare_frames() { +	method=$1 +	reftype=$2 +	format=$3 +	wpf=$4 + +	fmt=$(echo $format | tr '[:upper:]' '[:lower:]') +	size=$(vsp1_entity_get_size wpf.$wpf 1) + +	case $format in +	ARGB555) +		reference="frame-$reftype-$fmt-$size-alpha255.bin" +		;; +	ABGR32 | ARGB32) +		reference="frame-$reftype-$fmt-$size-alpha200.bin" +		;; +	XRGB555) +		# XRGB555 has the X bit hardcoded to 0 +		reference="frame-$reftype-$fmt-$size-alpha0.bin" +		;; +	XBGR32 | XRGB32) +		# The X bits are configurable with a default value of 255 +		reference="frame-$reftype-$fmt-$size-alpha255.bin" +		;; +	*) +		reference="frame-$reftype-$fmt-$size.bin" +		;; +	esac + +	result="pass" +	for frame in frame-*.bin ; do +		(compare_frame_$method $format $size $frame frames/$reference) || { +			mv $frame ${0/.sh/}-${frame/.bin/-$reftype-$fmt-$size.bin} ; +			result="fail" +		} +	done + +	echo $result +} + +compare_histogram() { +	histo_a=$1 +	histo_b=$2 + +	match='fail' +	diff -q $histo_a $histo_b > /dev/null && match='pass' + +	echo "Compared $histo_a and $histo_b: $match" | ./logger.sh check >> $logfile + +	if [ $match = 'pass' ] ; then +		return 0 +	else +		return 1 +	fi +} + +compare_histograms() { +	format=$1 +	wpf=$2 + +	fmt=$(echo $format | tr '[:upper:]' '[:lower:]') +	size=$(vsp1_entity_get_size wpf.$wpf 1) +	reference="histo-reference-$fmt-$size.bin" + +	result="pass" +	for histo in histo-*.bin ; do +		(compare_histogram $histo frames/$reference) || { +			mv $histo ${0/.sh/}-${histo/.bin/-$fmt.bin} ; +			result="fail" +		} +	done + +	echo $result +} + +# ------------------------------------------------------------------------------ +# Pipeline configuration +# + +pipe_none() { +	# Nothing to be done +	return +} + +pipe_rpf_bru() { +	ninputs=$1 + +	bru_output=$(vsp1_count_bru_inputs) + +	for input in `seq 0 1 $((ninputs-1))` ; do +		$mediactl -d $mdev -l "'$dev rpf.$input':1 -> '$dev bru':$input [1]" +	done +	$mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev wpf.0':0 [1]" +	$mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]" +} + +pipe_rpf_bru_uds() { +	bru_output=$(vsp1_count_bru_inputs) + +	$mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev bru':0 [1]" +	$mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev uds.0':0 [1]" +	$mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev wpf.0':0 [1]" +	$mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]" +} + +pipe_rpf_hgo() { +	$mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev wpf.0':0 [1]" +	$mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev hgo':0 [1]" +	$mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]" +} + +pipe_rpf_uds() { +	$mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev uds.0':0 [1]" +	$mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev wpf.0':0 [1]" +	$mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]" +} + +pipe_rpf_uds_bru() { +	bru_output=$(vsp1_count_bru_inputs) + +	$mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev uds.0':0 [1]" +	$mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev bru':0 [1]" +	$mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev wpf.0':0 [1]" +	$mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]" +} + +pipe_rpf_wpf() { +	rpf=$1 +	wpf=$2 + +	$mediactl -d $mdev -l "'$dev rpf.$rpf':1 -> '$dev wpf.$wpf':0 [1]" +	$mediactl -d $mdev -l "'$dev wpf.$wpf':1 -> '$dev wpf.$wpf output':0 [1]" +} + +pipe_reset() { +	$mediactl -d $mdev -r +} + +pipe_configure() { +	pipe=${1//-/_} +	shift 1 + +	pipe_reset +	pipe_$pipe $* +} + +# ------------------------------------------------------------------------------ +# Format Configuration +# + +format_v4l2_to_mbus() { +	case $1 in +	RGB332 | ARGB555 | XRGB555 | RGB565 | BGR24 | RGB24 | XBGR32 | XRGB32 | ABGR32 | ARGB32) +		echo "ARGB32"; +		;; + +	NV12M | NV16M | NV21M | NV61M | UYVY | VYUY | YUV420M | YUYV | YVYU) +		echo "AYUV32" +		;; + +	*) +		echo "Invalid format $1" >&2 +		echo -e "Valid formats are +\tRGB332, ARGB555, XRGB555, RGB565, BGR24, RGB24, +\tXBGR32, XRGB32, ABGR32, ARGB32, +\tNV12M, NV16M, NV21M, NV61M, UYVY, VYUY, YUV420M, YUYV, YVYU" >&2 +		exit 1 +	esac +} + +format_rpf() { +	format=$(format_v4l2_to_mbus $1) +	size=$2 +	rpf=$3 + +	$mediactl -d $mdev -V "'$dev rpf.$rpf':0 [fmt:$format/$size]" +} + +format_rpf_bru() { +	format=$(format_v4l2_to_mbus $1) +	size=$2 +	ninputs=$3 +	offset=0 + +	bru_output=$(vsp1_count_bru_inputs) + +	for input in `seq 0 1 $((ninputs-1))` ; do +		offset=$((offset+50)) +		$mediactl -d $mdev -V "'$dev rpf.$input':0 [fmt:$format/$size]" +		$mediactl -d $mdev -V "'$dev bru':$input   [fmt:$format/$size compose:($offset,$offset)/$size]" +	done + +	$mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$format/$size]" +	$mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]" +	$mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]" +} + +format_rpf_bru_uds() { +	infmt=$(format_v4l2_to_mbus $1) +	insize=$2 +	outfmt=$(format_v4l2_to_mbus $3) +	outsize=$4 + +	bru_output=$(vsp1_count_bru_inputs) + +	$mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]" +	$mediactl -d $mdev -V "'$dev bru':0 [fmt:$infmt/$insize]" +	$mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$infmt/$insize]" +	$mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]" +	$mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]" +	$mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]" +	$mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]" +} + +format_rpf_hgo() { +	format=$(format_v4l2_to_mbus $1) +	size=$2 +	crop=${3:+crop:$3} +	compose=${4:+compose:$4} + +	$mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]" +	$mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]" +	$mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]" +	$mediactl -d $mdev -V "'$dev hgo':0   [fmt:$format/$size $crop $compose]" +} + +format_rpf_uds() { +	infmt=$(format_v4l2_to_mbus $1) +	insize=$2 +	outfmt=$(format_v4l2_to_mbus $3) +	outsize=$4 + +	$mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]" +	$mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]" +	$mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]" +	$mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]" +	$mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]" +} + +format_rpf_uds_bru() { +	infmt=$(format_v4l2_to_mbus $1) +	insize=$2 +	outfmt=$(format_v4l2_to_mbus $3) +	outsize=$4 + +	bru_output=$(vsp1_count_bru_inputs) + +	$mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]" +	$mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]" +	$mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]" +	$mediactl -d $mdev -V "'$dev bru':0 [fmt:$infmt/$outsize]" +	$mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$infmt/$outsize]" +	$mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]" +	$mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]" +} + +format_rpf_wpf() { +	rpf=$1 +	wpf=$2 +	infmt=$(format_v4l2_to_mbus $3) +	size=$4 +	outfmt=$(format_v4l2_to_mbus $5) +	crop=$6 + +	if [ x$crop != 'x' ] ; then +		crop="crop:$crop" +		outsize=$(echo $crop | sed 's/.*\///') +	else +		outsize=$size +	fi + +	$mediactl -d $mdev -V "'$dev rpf.$rpf':0 [fmt:$infmt/$size]" +	$mediactl -d $mdev -V "'$dev wpf.$wpf':0 [fmt:$infmt/$size $crop]" +	$mediactl -d $mdev -V "'$dev wpf.$wpf':1 [fmt:$outfmt/$outsize]" +} + +format_wpf() { +	format=$(format_v4l2_to_mbus $1) +	size=$2 +	wpf=$3 + +	$mediactl -d $mdev -V "'$dev wpf.$wpf':0 [fmt:$format/$size]" +	$mediactl -d $mdev -V "'$dev wpf.$wpf':1 [fmt:$format/$size]" +} + +format_configure() { +	pipe=${1//-/_} +	shift 1 + +	format_$pipe $* +} + +# ------------------------------------------------------------------------------ +# Test run +# + +test_init() { +	logfile=${1/sh/log} +	features=$2 + +	rm -f $logfile +	rm -f *.bin + +	for mdev in /dev/media* ; do +		match='true' +		for feature in $features ; do +			$(vsp1_has_feature $feature) || { +				match='false'; +				break; +			} +		done + +		if [ $match == 'true' ] ; then +			break +		fi +	done + +	if [ $match == 'false' ] ; then +		echo "No device found with feature set $features" | ./logger.sh config >> $logfile +		exit 1 +	fi + +	dev=$(vsp1_device $mdev) +	echo "Using device $mdev ($dev)" | ./logger.sh config >> $logfile + +	vsp_runner=./vsp-runner.sh +} + +test_start() { +	echo "Testing $1" | ./logger.sh >> $logfile +	echo -n "Testing $1: " >&2 +} + +test_complete() { +	echo "Done: $1" | ./logger.sh >> $logfile +	echo $1 >&2 + +	rm -f frame-*.bin +	rm -f histo-*.bin +} diff --git a/scripts/vsp-runner.sh b/scripts/vsp-runner.sh new file mode 100755 index 0000000..e92eda1 --- /dev/null +++ b/scripts/vsp-runner.sh @@ -0,0 +1,135 @@ +#!/bin/sh + +set -e + +source vsp-lib.sh + +mediactl='media-ctl' +yavta='yavta' + +# ------------------------------------------------------------------------------ +# Format retrieval +# + +frame_reference() { +	format=$1 +	size=$2 + +	lcfmt=`echo $infmt | tr '[:upper:]' '[:lower:]'` + +	case $format in +	ARGB555) +		echo "frames/frame-reference-$lcfmt-$size-alpha255.bin" +		;; +	ABGR32 | ARGB32) +		echo "frames/frame-reference-$lcfmt-$size-alpha200.bin" +		;; +	XRGB555 | XBGR32 | XRGB32) +		echo "frames/frame-reference-$lcfmt-$size-alpha0.bin" +		;; +	*) +		echo "frames/frame-reference-$lcfmt-$size.bin" +		;; +	esac +} + +# ------------------------------------------------------------------------------ +# Parse the command line and retrieve the formats +# + +syntax() { +	echo "Syntax: vsp-runner.sh dev cmd [...]" +	echo "" +	echo "Supported commands:" +	echo "    hgo [options]" +	echo "    input index infmt [options]" +	echo "    output index outfmt [options]" +} + +parse() { +	if [ $# -lt 2 ] ; then +		syntax +		return 1 +	fi + +	mdev=$1 +	dev=`$mediactl -d $mdev -p | grep 'bus info' | sed 's/.*platform://'` + +	if [ -z $dev ] ; then +		echo "Error: Device $dev doesn't exist" +		syntax +		return 1 +	fi + +	cmd=$2 + +	case $cmd in +	hgo) +		options=$3 +		;; + +	input) +		index=$3 +		infmt=$4 +		options=$5 +		;; + +	output) +		index=$3 +		outfmt=$4 +		options=$5 +		;; + +	*) +		echo "Invalid command $cmd" +		;; +	esac +} + +# ------------------------------------------------------------------------------ +# Execute the command +# + +execute() { +	case $cmd in +	hgo) +		if [ "x$options" = xinfinite ] ; then +			$yavta -c -n 4 \ +				`$mediactl -d $mdev -e "$dev hgo histo"` +		else +			$yavta -c10 -n 10 --file=histo-#.bin $options \ +				`$mediactl -d $mdev -e "$dev hgo histo"` +		fi +		;; + +	input) +		rpf=rpf.$index +		size=$(vsp1_entity_get_size $rpf 0) + +		file=$(frame_reference $infmt $size) + +		if [ "x$options" = xinfinite ] ; then +			$yavta -c -n 4 -f $infmt -s $size --file=$file $options \ +				`$mediactl -d $mdev -e "$dev $rpf input"` +		else +			$yavta -c10 -n 4 -f $infmt -s $size --file=$file $options \ +				`$mediactl -d $mdev -e "$dev $rpf input"` +		fi +		;; + +	output) +		wpf=wpf.$index +		size=$(vsp1_entity_get_size $wpf 1) + +		if [ "x$options" = xinfinite ] ; then +			$yavta -c -n 4 -f $outfmt -s $size \ +				`$mediactl -d $mdev -e "$dev $wpf output"` +		else +			$yavta -c10 -n 4 -f $outfmt -s $size --skip 7 -F $options \ +				`$mediactl -d $mdev -e "$dev $wpf output"` +		fi +		;; +	esac +} + +parse $* && execute  | 
