diff options
28 files changed, 1472 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4e4a02d --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +SUBDIRS=data scripts tests + +recursive=all clean install + +all: + +$(recursive): + @target=$@ ; \ + for subdir in $(SUBDIRS); do \ + echo "Making $$target in $$subdir" ; \ + $(MAKE) -C $$subdir $$target; \ + done @@ -0,0 +1,57 @@ +vsp-tests +--------- + +Test suite for the Renesas R-Car VSP1 and VSP2 video processing engines. + +You can find the latest version of vsp-tests in the project's git tree at + + git://git.ideasonboard.com/renesas/vsp-tests.git + http://git.ideasonboard.com/renesas/vsp-tests.git + + +-------- +Building +-------- + +The vsp-tests suite requires the following tools to be installed on the host +to generate the test script and test data. + +* make +* python + +After installing the needed packages, you can build the test suite by running + + make + +in the vsp-tests root directory. Then, to install the test suite, run + + make install INSTALL_DIR=/path/to/target/directory + +This will copy the test scripts and data to the target directory to be copied +or exported to the host. As test data take more than 200MB of disk space usage +of nfsroot is recommended to run the tests. + + +-------------------- +Runtime Dependencies +-------------------- + +The tests scripts require the following tools to be installed on the target +system in a directory included in $PATH. + +* compare (part of ImageMagick) +* media-ctl (part of v4l-utils, available at git://linuxtv.org/v4l-utils.git) +* raw2rgbpnm (available at git://git.retiisi.org.uk/~sailus/raw2rgbpnm.git) +* yavta (available at git://git.ideasonboard.org/yavta.git) + +All but the HGO test can be run with the latest version of these tools. To +test the HGO, the 'metadata' branch of 'yavta' is currently needed. + + +----------------- +Running the Tests +----------------- + +The test scripts are named vsp-unit-test-[0-9]*.sh. They can be run directly +from the test suite root directory. + diff --git a/data/Makefile b/data/Makefile new file mode 100644 index 0000000..768a346 --- /dev/null +++ b/data/Makefile @@ -0,0 +1,12 @@ +SUBDIRS=frames + +recursive=all clean install + +all: + +$(recursive): + @target=$@ ; \ + for subdir in $(SUBDIRS); do \ + echo "Making $$target in $$subdir" ; \ + $(MAKE) -C $$subdir $$target; \ + done diff --git a/data/frames/.gitignore b/data/frames/.gitignore new file mode 100644 index 0000000..a8a0dce --- /dev/null +++ b/data/frames/.gitignore @@ -0,0 +1 @@ +*.bin diff --git a/data/frames/Makefile b/data/frames/Makefile new file mode 100644 index 0000000..326e447 --- /dev/null +++ b/data/frames/Makefile @@ -0,0 +1,9 @@ +all: + @./gen-frames.py + +clean: + @rm *.bin + +install: + mkdir -p $(INSTALL_DIR)/frames/ + cp frame-reference-*.bin $(INSTALL_DIR)/frames/ diff --git a/data/frames/frame-reference-1024x768.rgb.gz b/data/frames/frame-reference-1024x768.rgb.gz Binary files differnew file mode 100644 index 0000000..480239c --- /dev/null +++ b/data/frames/frame-reference-1024x768.rgb.gz diff --git a/data/frames/frame-reference-1024x768.yuv.gz b/data/frames/frame-reference-1024x768.yuv.gz Binary files differnew file mode 100644 index 0000000..55d3e7a --- /dev/null +++ b/data/frames/frame-reference-1024x768.yuv.gz diff --git a/data/frames/frame-reference-640x480.rgb.gz b/data/frames/frame-reference-640x480.rgb.gz Binary files differnew file mode 100644 index 0000000..7c5bd16 --- /dev/null +++ b/data/frames/frame-reference-640x480.rgb.gz diff --git a/data/frames/frame-reference-640x480.yuv.gz b/data/frames/frame-reference-640x480.yuv.gz Binary files differnew file mode 100644 index 0000000..3f27be3 --- /dev/null +++ b/data/frames/frame-reference-640x480.yuv.gz diff --git a/data/frames/frame-scaled-1024x768.rgb.gz b/data/frames/frame-scaled-1024x768.rgb.gz Binary files differnew file mode 100644 index 0000000..fba101d --- /dev/null +++ b/data/frames/frame-scaled-1024x768.rgb.gz diff --git a/data/frames/frame-scaled-1024x768.yuv.gz b/data/frames/frame-scaled-1024x768.yuv.gz Binary files differnew file mode 100644 index 0000000..d3c3aae --- /dev/null +++ b/data/frames/frame-scaled-1024x768.yuv.gz diff --git a/data/frames/frame-scaled-640x480.rgb.gz b/data/frames/frame-scaled-640x480.rgb.gz Binary files differnew file mode 100644 index 0000000..08c1be8 --- /dev/null +++ b/data/frames/frame-scaled-640x480.rgb.gz diff --git a/data/frames/frame-scaled-640x480.yuv.gz b/data/frames/frame-scaled-640x480.yuv.gz Binary files differnew file mode 100644 index 0000000..821919f --- /dev/null +++ b/data/frames/frame-scaled-640x480.yuv.gz diff --git a/data/frames/gen-frames.py b/data/frames/gen-frames.py new file mode 100755 index 0000000..4742793 --- /dev/null +++ b/data/frames/gen-frames.py @@ -0,0 +1,350 @@ +#!/usr/bin/python + +import copy +import glob +import gzip +import itertools +import operator +import re +import struct +import sys + +class FormatRGB: + def __init__(self, name, mapping): + self.name = name + self.mapping = copy.copy(mapping) + self.depth = sum(v[1] for v in mapping.values()) + + if self.mapping.has_key('a'): + self.alpha_bits = self.mapping['a'][1] + elif self.mapping.has_key('x'): + self.alpha_bits = self.mapping['x'][1] + else: + self.alpha_bits = 0 + + def alpha(self, alpha): + if self.mapping.has_key('a'): + return (alpha >> (8 - self.mapping['a'][1])) << self.mapping['a'][0] + elif self.mapping.has_key('x'): + return (alpha >> (8 - self.mapping['x'][1])) << self.mapping['x'][0] + else: + return 0 + + def generate_8(self, width, height, rgb): + output = [] + for i in xrange(width * height): + r, g, b = rgb[i] + pixel = ((r >> (8 - self.mapping['r'][1])) << self.mapping['r'][0]) \ + | ((g >> (8 - self.mapping['g'][1])) << self.mapping['g'][0]) \ + | ((b >> (8 - self.mapping['b'][1])) << self.mapping['b'][0]) + output.append(struct.pack('B', pixel)) + return ''.join(output) + + def generate_16(self, width, height, rgb, alpha): + output = [] + for i in xrange(width * height): + r, g, b = rgb[i] + pixel = ((r >> (8 - self.mapping['r'][1])) << self.mapping['r'][0]) \ + | ((g >> (8 - self.mapping['g'][1])) << self.mapping['g'][0]) \ + | ((b >> (8 - self.mapping['b'][1])) << self.mapping['b'][0]) \ + | self.alpha(alpha) + output.append(struct.pack('<H', pixel)) + return ''.join(output) + + def generate_24(self, width, height, rgb): + output = [] + for i in xrange(width * height): + r, g, b = rgb[i] + pixel = ((r >> (8 - self.mapping['r'][1])) << self.mapping['r'][0]) \ + | ((g >> (8 - self.mapping['g'][1])) << self.mapping['g'][0]) \ + | ((b >> (8 - self.mapping['b'][1])) << self.mapping['b'][0]) + output.append(struct.pack('<I', pixel)[0:3]) + return ''.join(output) + + def generate_32(self, width, height, rgb, alpha): + output = [] + for i in xrange(width * height): + r, g, b = rgb[i] + pixel = ((r >> (8 - self.mapping['r'][1])) << self.mapping['r'][0]) \ + | ((g >> (8 - self.mapping['g'][1])) << self.mapping['g'][0]) \ + | ((b >> (8 - self.mapping['b'][1])) << self.mapping['b'][0]) \ + | self.alpha(alpha) + output.append(struct.pack('<I', pixel)) + return ''.join(output) + + def convert(self, width, height, rgb, alpha): + if self.depth == 8: + return self.generate_8(width, height, rgb) + elif self.depth == 16: + return self.generate_16(width, height, rgb, alpha) + elif self.depth == 24: + return self.generate_24(width, height, rgb) + elif self.depth == 32: + return self.generate_32(width, height, rgb, alpha) + else: + raise RuntimeError, 'Invalid depth %s' % self.depth + + def bin(self, bins, val): + bins[val >> 2] += 1 + + def histogram(self, width, height, rgb): + rgb_min = [255, 255, 255] + rgb_max = [0, 0, 0] + rgb_sum = [0, 0, 0] + rgb_bins = [[0] * 64, [0] * 64, [0] * 64] + + for i in xrange(width * height): + pixel = rgb[i] + + rgb_min = map(min, pixel, rgb_min) + rgb_max = map(max, pixel, rgb_max) + rgb_sum = map(operator.add, pixel, rgb_sum) + + map(self.bin, rgb_bins, pixel) + + output = [] + for i in xrange(len(rgb_min)): + output.append(struct.pack('BBBB', rgb_min[i], 0, rgb_max[i], 0)) + output.append(struct.pack('<3I', *rgb_sum)) + for i in xrange(len(rgb_bins)): + output.append(struct.pack('<64I', *rgb_bins[i])) + + return ''.join(output) + + def compose(self, ninputs, width, height, rgb): + output = [(0, 0, 0)] * (width * height) + offset = 50 + + for input in xrange(ninputs): + length = width - offset + for y in xrange(height - offset): + dst_offset = (y + offset) * width + offset + src_offset = y * width + output[dst_offset:dst_offset+length] = rgb[src_offset:src_offset+length] + offset += 50 + + return ''.join(chr(d) for d in list(itertools.chain.from_iterable(output))) + + +class FormatYUVPacked: + def __init__(self, name, mapping): + self.name = name + self.mapping = copy.copy(mapping) + + def convert(self, width, height, yuv): + output = [] + for i in xrange(width * height / 2): + pixel = yuv[i*4:(i+1)*4] + pixel = (pixel[self.mapping[0]], pixel[self.mapping[1]], + pixel[self.mapping[2]], pixel[self.mapping[3]]) + output.extend(pixel) + return ''.join(output) + + def bin(self, bins, val): + bins[val >> 2] += 1 + + def histogram(self, width, height, yuv): + vyu_min = [255, 255, 255] + vyu_max = [0, 0, 0] + vyu_sum = [0, 0, 0] + vyu_bins = [[0] * 64, [0] * 64, [0] * 64] + + for y in xrange(height): + for x in xrange(width / 2): + offset = y * width * 2 + x * 4 + u0 = ord(yuv[offset]) + y0 = ord(yuv[offset+1]) + v0 = ord(yuv[offset+2]) + y1 = ord(yuv[offset+3]) + + if x != width / 2 - 1: + u2 = ord(yuv[offset+4]) + v2 = ord(yuv[offset+6]) + u1 = (u0 + u2) / 2 + v1 = (v0 + v2) / 2 + else: + u1 = u0 + v1 = v1 + + for vyu in ((v0, y0, u0), (v1, y1, u1)): + vyu_min = map(min, vyu, vyu_min) + vyu_max = map(max, vyu, vyu_max) + vyu_sum = map(operator.add, vyu, vyu_sum) + + map(self.bin, vyu_bins, vyu) + + output = [] + for i in xrange(len(vyu_min)): + output.append(struct.pack('BBBB', vyu_min[i], 0, vyu_max[i], 0)) + output.append(struct.pack('<3I', *vyu_sum)) + for i in xrange(len(vyu_bins)): + output.append(struct.pack('<64I', *vyu_bins[i])) + + return ''.join(output) + + def compose(self, ninputs, width, height, yuv): + output = ['\0'] * (width * height * 2) + offset = 50 + + for input in xrange(ninputs): + length = (width - offset) * 2 + for y in xrange(height - offset): + dst_offset = ((y + offset) * width + offset) * 2 + src_offset = y * width * 2 + output[dst_offset:dst_offset+length] = yuv[src_offset:src_offset+length] + offset += 50 + + return ''.join(output) + + +class FormatNV: + def __init__(self, name, hsub, vsub, mapping): + self.name = name + self.hsub = hsub + self.vsub = vsub + self.mapping = copy.copy(mapping) + + def convert(self, width, height, yuv): + output = [] + + for i in xrange(width * height): + output.append(yuv[2*i+1]) + + for y in xrange(height / self.vsub): + for x in xrange(width / 2): + offset = (y * self.vsub * width * 2) + x * 4 + uv = (yuv[offset], yuv[offset+2]) + uv = (uv[self.mapping[0]], uv[self.mapping[1]]) + output.extend(uv) + + return ''.join(output) + + +class FormatYUVPlanar: + def __init__(self, name, hsub, vsub, mapping): + self.name = name + self.hsub = hsub + self.vsub = vsub + self.mapping = copy.copy(mapping) + + def convert(self, width, height, yuv): + output = [] + + for i in xrange(width * height): + output.append(yuv[2*i+1]) + + for y in xrange(height / self.vsub): + for x in xrange(width / 2): + offset = (y * self.vsub * width * 2) + x * 4 + u = yuv[offset + self.mapping[0] * 2] + output.append(u) + + for y in xrange(height / self.vsub): + for x in xrange(width / 2): + offset = (y * self.vsub * width * 2) + x * 4 + v = yuv[offset + self.mapping[1] * 2] + output.append(v) + + return ''.join(output) + + +formats_rgb = { + 'rgb332': FormatRGB('rgb332', {'r': (5, 3), 'g': (2, 3), 'b': (0, 2)}), + 'rgb565': FormatRGB('rgb565', {'r': (11, 5), 'g': (5, 6), 'b': (0, 5)}), + 'bgr24': FormatRGB('bgr24', {'r': (16, 8), 'g': (8, 8), 'b': (0, 8)}), + 'rgb24': FormatRGB('rgb24', {'r': (0, 8), 'g': (8, 8), 'b': (16, 8)}), +} + +formats_argb = { + 'argb555': FormatRGB('argb555', {'a': (15, 1), 'r': (10, 5), 'g': (5, 5), 'b': (0, 5)}), + 'xrgb555': FormatRGB('xrgb555', {'x': (15, 1), 'r': (10, 5), 'g': (5, 5), 'b': (0, 5)}), + 'abgr32': FormatRGB('abgr32', {'a': (24, 8), 'r': (16, 8), 'g': (8, 8), 'b': (0, 8)}), + 'argb32': FormatRGB('argb32', {'a': (0, 8), 'r': (8, 8), 'g': (16, 8), 'b': (24, 8)}), + 'xbgr32': FormatRGB('xbgr32', {'x': (24, 8), 'r': (16, 8), 'g': (8, 8), 'b': (0, 8)}), + 'xrgb32': FormatRGB('xrgb32', {'x': (0, 8), 'r': (8, 8), 'g': (16, 8), 'b': (24, 8)}), +} + +formats_yuv = { + 'uyvy': FormatYUVPacked('uyvy', (0, 1, 2, 3)), + 'vyuy': FormatYUVPacked('vyuy', (2, 1, 0, 3)), + 'yuyv': FormatYUVPacked('yuyv', (1, 0, 3, 2)), + 'yvyu': FormatYUVPacked('yvyu', (1, 2, 3, 0)), + 'nv12m': FormatNV('nv12m', 2, 2, (0, 1)), + 'nv21m': FormatNV('nv21m', 2, 2, (1, 0)), + 'nv16m': FormatNV('nv16m', 2, 1, (0, 1)), + 'nv61m': FormatNV('nv61m', 2, 1, (1, 0)), + 'yuv420m': FormatYUVPlanar('yuv420m', 2, 2, (0, 1)), +} + +resolutions = ((640, 480), (1024, 768)) + +def main(argv): + re_fname = re.compile('frame-([a-z]*)-([0-9]*)x([0-9]*).([a-z]*).gz') + + for fname in glob.glob('*.gz'): + match = re_fname.match(fname) + if not match: + continue + + typ = match.group(1) + res = (int(match.group(2)), int(match.group(3))) + fmt = match.group(4) + + if fmt == 'rgb': + rgb = gzip.open(fname, 'rb').read() + rgb = [struct.unpack('BBB', rgb[i*3:(i+1)*3]) for i in xrange(len(rgb) / 3)] + + for format in formats_rgb.values(): + bin_fname = 'frame-%s-%s-%ux%u.bin' % (typ, format.name, res[0], res[1]) + print 'Generating %s' % bin_fname + bin = format.convert(res[0], res[1], rgb, 0) + file(bin_fname, 'wb').write(bin) + + for format in formats_argb.values(): + for alpha in (0, 100, 200, 255): + if format.alpha_bits == 1 and alpha not in (0, 255): + continue + bin_fname = 'frame-%s-%s-%ux%u-alpha%u.bin' % (typ, format.name, res[0], res[1], alpha) + print 'Generating %s' % bin_fname + bin = format.convert(res[0], res[1], rgb, alpha) + file(bin_fname, 'wb').write(bin) + + format = formats_rgb['rgb24'] + + bin_fname = 'histo-%s-%s-%ux%u.bin' % (typ, format.name, res[0], res[1]) + print 'Generating %s' % bin_fname + bin = format.histogram(res[0], res[1], rgb) + file(bin_fname, 'wb').write(bin) + + if typ == 'reference' and res[0] == 1024 and res[1] == 768: + for ninputs in xrange(1, 6): + bin_fname = 'frame-composed-%u-%s-%ux%u.bin' % (ninputs, format.name, res[0], res[1]) + print 'Generating %s' % bin_fname + bin = format.compose(ninputs, res[0], res[1], rgb) + file(bin_fname, 'wb').write(bin) + + elif fmt == 'yuv': + yuv = gzip.open(fname, 'rb').read() + + for format in formats_yuv.values(): + bin_fname = 'frame-%s-%s-%ux%u.bin' % (typ, format.name, res[0], res[1]) + print 'Generating %s' % bin_fname + bin = format.convert(res[0], res[1], yuv) + file(bin_fname, 'wb').write(bin) + + format = formats_yuv['uyvy'] + bin_fname = 'histo-%s-%s-%ux%u.bin' % (typ, format.name, res[0], res[1]) + print 'Generating %s' % bin_fname + bin = format.histogram(res[0], res[1], yuv) + file(bin_fname, 'wb').write(bin) + + if typ == 'reference' and res[0] == 1024 and res[1] == 768: + for ninputs in xrange(1, 6): + bin_fname = 'frame-composed-%u-%s-%ux%u.bin' % (ninputs, format.name, res[0], res[1]) + print 'Generating %s' % bin_fname + bin = format.compose(ninputs, res[0], res[1], yuv) + file(bin_fname, 'wb').write(bin) + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) 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 diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..6586b29 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,8 @@ +SCRIPTS=$(wildcard *.sh) + +all: + +clean: + +install: + cp $(SCRIPTS) $(INSTALL_DIR)/ diff --git a/tests/vsp-unit-test-0001.sh b/tests/vsp-unit-test-0001.sh new file mode 100755 index 0000000..2cb0cb3 --- /dev/null +++ b/tests/vsp-unit-test-0001.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +# +# Test WPF packing in RGB mode. Use a RPF -> WPF pipeline with a fixed ARGB32 +# format on the input and capture output frames in all RGB formats supported +# by the WPF. +# + +source vsp-lib.sh + +features="rpf.0 wpf.0" +formats="RGB332 ARGB555 XRGB555 RGB565 BGR24 RGB24 ABGR32 ARGB32 XBGR32 XRGB32" + +test_wpf_packing() { + test_start "WPF packing in $format" + + pipe_configure rpf-wpf 0 0 | ./logger.sh config >> $logfile + format_configure rpf-wpf 0 0 \ + ARGB32 1024x768 $format | ./logger.sh config >> $logfile + + $vsp_runner $mdev input 0 ARGB32 | ./logger.sh input.0 >> $logfile & + $vsp_runner $mdev output 0 $format | ./logger.sh output.0 >> $logfile + + result=$(compare_frames exact reference $format 0) + + test_complete $result +} + +test_run() { + for format in $formats ; do + test_wpf_packing $format + done +} + +test_init $0 "$features" +test_run diff --git a/tests/vsp-unit-test-0002.sh b/tests/vsp-unit-test-0002.sh new file mode 100755 index 0000000..e2602d8 --- /dev/null +++ b/tests/vsp-unit-test-0002.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +# +# Test WPF packing in YUV mode. Use a RPF -> WPF pipeline with a fixed YUYV +# format on the input and capture output frames in all YUV formats supported +# by the WPF. +# + +source vsp-lib.sh + +features="rpf.0 wpf.0" +formats="NV12M NV16M NV21M NV61M UYVY VYUY YUV420M YUYV YVYU" + +test_wpf_packing() { + test_start "WPF packing in $format" + + pipe_configure rpf-wpf 0 0 | ./logger.sh config >> $logfile + format_configure rpf-wpf 0 0 \ + YUYV 1024x768 $format | ./logger.sh config >> $logfile + + $vsp_runner $mdev input 0 YUYV | ./logger.sh input.0 >> $logfile & + $vsp_runner $mdev output 0 $format | ./logger.sh output.0 >> $logfile + + result=$(compare_frames fuzzy reference $format 0) + + test_complete $result +} + +test_run() { + for format in $formats ; do + test_wpf_packing $format + done +} + +test_init $0 "$features" +test_run diff --git a/tests/vsp-unit-test-0003.sh b/tests/vsp-unit-test-0003.sh new file mode 100755 index 0000000..ff81509 --- /dev/null +++ b/tests/vsp-unit-test-0003.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +# +# Test downscaling and upscaling in RGB and YUV modes. Use a RPF -> UDS -> WPF +# pipeline with identical input and output formats. +# + +source vsp-lib.sh + +features="rpf.0 uds wpf.0" +formats="RGB24 UYVY" + +test_scale() { + format=$1 + insize=$2 + outsize=$3 + + test_start "scaling from $insize to $outsize in $format" + + pipe_configure rpf-uds | ./logger.sh config >> $logfile + format_configure rpf-uds \ + $format $insize $format $outsize | ./logger.sh config >> $logfile + + $vsp_runner $mdev input 0 $format | ./logger.sh input.0 >> $logfile & + $vsp_runner $mdev output 0 $format | ./logger.sh output.0 >> $logfile + + result=$(compare_frames exact scaled $format 0) + + test_complete $result +} + +test_run() { + for format in $formats ; do + test_scale $format 1024x768 640x480 + test_scale $format 640x480 1024x768 + done +} + +test_init $0 "$features" +test_run diff --git a/tests/vsp-unit-test-0004.sh b/tests/vsp-unit-test-0004.sh new file mode 100755 index 0000000..af5dfdb --- /dev/null +++ b/tests/vsp-unit-test-0004.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +# +# Test 1D histogram generation. Use a RPF -> WPF pipeline with the HGO hooked +# up at the RPF output. +# + +source vsp-lib.sh + +features="hgo rpf.0 wpf.0" +formats="RGB24 UYVY" + +test_histogram() { + test_start "histogram in $format" + + pipe_configure rpf-hgo | ./logger.sh config >> $logfile + format_configure rpf-hgo \ + $format 1024x768 | ./logger.sh config >> $logfile + + $vsp_runner $mdev m2m-hgo $format $format | ./logger.sh config >> $logfile + $vsp_runner $mdev hgo | ./logger.sh hgo >> $logfile & + $vsp_runner $mdev input 0 $format | ./logger.sh input.0 >> $logfile & + $vsp_runner $mdev output 0 $format | ./logger.sh output.0 >> $logfile + + result=$(compare_histograms $format 0) + + test_complete $result +} + +test_run() { + for format in $formats ; do + test_histogram $format + done +} + +test_init $0 "$features" +test_run diff --git a/tests/vsp-unit-test-0005.sh b/tests/vsp-unit-test-0005.sh new file mode 100755 index 0000000..aeb0ca2 --- /dev/null +++ b/tests/vsp-unit-test-0005.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +# +# Test RPF -> WPF with all RPF and WPF instances in sequence. The format +# doesn't matter much, use RGB24 to simplify frame comparison. +# + +source vsp-lib.sh + +features="rpf.0 rpf.1 wpf.0 wpf.1" +format=RGB24 + +test_rpf() { + rpf=$1 + + test_start "RPF.$rpf" + + pipe_configure rpf-wpf $rpf 0 | ./logger.sh config >> $logfile + format_configure rpf-wpf $rpf 0 \ + $format 1024x768 $format | ./logger.sh config >> $logfile + + $vsp_runner $mdev input $rpf $format | ./logger.sh input.0 >> $logfile & + $vsp_runner $mdev output 0 $format | ./logger.sh output.0 >> $logfile + + result=$(compare_frames exact reference $format 0) + + test_complete $result +} + +test_wpf() { + wpf=$1 + + test_start "WPF.$wpf" + + pipe_configure rpf-wpf 0 $wpf | ./logger.sh config >> $logfile + format_configure rpf-wpf 0 $wpf \ + $format 1024x768 $format | ./logger.sh config >> $logfile + + $vsp_runner $mdev input 0 $format | ./logger.sh input.0 >> $logfile & + $vsp_runner $mdev output $wpf $format | ./logger.sh output.0 >> $logfile + + result=$(compare_frames exact reference $format $wpf) + + test_complete $result +} + +test_run() { + num_rpfs=$(vsp1_count_rpfs) + num_wpfs=$(vsp1_count_wpfs) + + for rpf in `seq 0 1 $((num_rpfs-1))` ; do + test_rpf $rpf + done + + # Skip WPF.0, it has already been tested during the RPF tests. + for wpf in `seq $((num_wpfs-1))` ; do + test_wpf $wpf + done +} + +test_init $0 "$features" +test_run diff --git a/tests/vsp-unit-test-0006.sh b/tests/vsp-unit-test-0006.sh new file mode 100755 index 0000000..0ae4259 --- /dev/null +++ b/tests/vsp-unit-test-0006.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# +# Test invalid pipelines, without an RPF or without a WPF. +# + +source vsp-lib.sh + +features="rpf.0 wpf.0" +format=RGB24 + +test_no_rpf() { + test_start "invalid pipeline with no RPF" + + pipe_configure none | ./logger.sh config >> $logfile + format_configure wpf \ + $format 1024x768 0 | ./logger.sh config >> $logfile + + $vsp_runner $mdev output 0 $format | ./logger.sh input.0 >> $logfile + + # The test always passes if the kernel doesn't crash + test_complete pass +} + +test_no_wpf() { + test_start "invalid pipeline with no WPF" + + pipe_configure none | ./logger.sh config >> $logfile + format_configure rpf \ + $format 1024x768 0 | ./logger.sh config >> $logfile + + $vsp_runner $mdev input 0 $format | ./logger.sh input.0 >> $logfile + + # The test always passes if the kernel doesn't crash + test_complete pass +} + +test_run() { + test_no_rpf + test_no_wpf +} + +test_init $0 "$features" +test_run diff --git a/tests/vsp-unit-test-0007.sh b/tests/vsp-unit-test-0007.sh new file mode 100755 index 0000000..c124c29 --- /dev/null +++ b/tests/vsp-unit-test-0007.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +# +# Test composition through the BRU in RGB and YUV formats. +# + +source vsp-lib.sh + +features="rpf.0 rpf.1 bru wpf.0" +formats="RGB24 UYVY" + +test_bru() { + format=$1 + ninputs=$2 + + test_start "BRU in $format with $ninputs inputs" + + pipe_configure rpf-bru $ninputs | ./logger.sh config >> $logfile + format_configure rpf-bru \ + $format 1024x768 $ninputs | ./logger.sh config >> $logfile + + for input in `seq 0 1 $((ninputs-1))` ; do + $vsp_runner $mdev input $input $format | ./logger.sh input.$input >> $logfile & + done + $vsp_runner $mdev output 0 $format | ./logger.sh output.0 >> $logfile + + result=$(compare_frames fuzzy composed-$ninputs $format 0) + + test_complete $result +} + +test_run() { + max_inputs=$(vsp1_count_bru_inputs) + + for format in $formats ; do + for ninputs in `seq $max_inputs` ; do + test_bru $format $ninputs + done + done +} + +test_init $0 "$features" +test_run diff --git a/tests/vsp-unit-test-0008.sh b/tests/vsp-unit-test-0008.sh new file mode 100755 index 0000000..b3b0510 --- /dev/null +++ b/tests/vsp-unit-test-0008.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +# +# Test downscaling and upscaling in RGB and YUV modes with a BRU inserted in +# the pipeline, both before and after the scaler. +# + +source vsp-lib.sh + +features="bru rpf.0 uds wpf.0" +formats="RGB24 UYVY" + +test_scale() { + format=$1 + insize=$2 + outsize=$3 + order=$4 + + if [ $order = 'after' ] ; then + pipe=rpf-bru-uds + else + pipe=rpf-uds-bru + fi + + test_start "scaling from $insize to $outsize in $format $order BRU" + + pipe_configure $pipe | ./logger.sh config >> $logfile + format_configure $pipe \ + $format $insize $format $outsize | ./logger.sh config >> $logfile + + $vsp_runner $mdev input 0 $format | ./logger.sh input.0 >> $logfile & + $vsp_runner $mdev output 0 $format | ./logger.sh output.0 >> $logfile + + result=$(compare_frames exact scaled $format 0) + + test_complete $result +} + +test_run() { + for format in $formats ; do + test_scale $format 1024x768 640x480 before + test_scale $format 640x480 1024x768 before + test_scale $format 1024x768 640x480 after + test_scale $format 640x480 1024x768 after + done +} + +test_init $0 "$features" +test_run |