vsp-lib: Use gen-image to generate frames at runtime
[renesas/vsp-tests.git] / scripts / vsp-lib.sh
1 #!/bin/sh
2
3 genimage='./gen-image'
4 mediactl='media-ctl'
5 yavta='yavta'
6
7 # ------------------------------------------------------------------------------
8 # Miscellaneous
9 #
10
11 vsp1_device() {
12         $mediactl -d $mdev -p | grep 'bus info' | sed 's/.*platform://'
13 }
14
15 vsp1_has_feature() {
16         feature=$1
17
18         $mediactl -d $mdev -p | grep -q -- "- entity.*$feature"
19 }
20
21 vsp1_count_rpfs() {
22         $mediactl -d $mdev -p | grep -- '- entity.*rpf.[0-9] [^i]' | wc -l
23 }
24
25 vsp1_count_wpfs() {
26         $mediactl -d $mdev -p | grep -- '- entity.*wpf.[0-9] [^o]' | wc -l
27 }
28
29 vsp1_count_bru_inputs() {
30         num_pads=`media-ctl -p | grep 'entity.*bru' | sed 's/.*(\([0-9]\) pads.*/\1/'`
31         echo $((num_pads-1))
32 }
33
34 vsp1_entity_get_size() {
35         entity=$1
36         pad=$2
37
38         $mediactl -d $mdev --get-v4l2 "'$dev $entity':$pad" | grep fmt | \
39               sed 's/.*\/\([0-9x]*\).*/\1/'
40 }
41
42 # -----------------------------------------------------------------------------
43 # Referance frame generation
44 #
45
46 reference_frame() {
47         local file=$1
48         local reftype=$2
49         local format=$3
50         local size=$4
51
52         local alpha=
53         local options=
54
55         case $reftype in
56         reference | scaled)
57                 ;;
58         composed-*)
59                 options="$options -c ${reftype/composed-/}"
60                 ;;
61         esac
62
63         case $format in
64         ARGB555)
65                 alpha=255
66                 ;;
67         ABGR32 | ARGB32)
68                 alpha=200
69                 ;;
70         XRGB555)
71                 # XRGB555 has the X bit hardcoded to 0
72                 alpha=0
73                 ;;
74         XBGR32 | XRGB32)
75                 # The X bits are configurable with a default value of 255
76                 alpha=255
77                 ;;
78         *)
79                 alpha=255
80                 ;;
81         esac
82
83         $(format_v4l2_is_yuv $format) && options="$options -y"
84
85         $genimage -f $format -s $size -a $alpha $options -o $file \
86                 frames/frame-reference-1024x768.pnm
87 }
88
89 reference_histogram() {
90         local file=$1
91         local format=$2
92         local size=$3
93
94         local yuv=
95         $(format_v4l2_is_yuv $format) && yuv="-y"
96
97         $genimage -f $format $yuv -s $size -H $file \
98                 frames/frame-reference-1024x768.pnm
99 }
100
101 # ------------------------------------------------------------------------------
102 # Image and histogram comparison
103 #
104
105 #
106 # Compare the two frames for exact match.
107 #
108 compare_frame_exact() {
109         img_a=$3
110         img_b=$4
111
112         match='fail'
113         diff -q $img_a $img_b > /dev/null && match='pass'
114
115         echo "Compared $img_a and $img_b: $match" | ./logger.sh check >> $logfile
116
117         if [ $match = 'pass' ] ; then
118                 return 0
119         else
120                 return 1
121         fi
122 }
123
124 #
125 # Compare the two frames using a fuzzy match algorithm to account for errors
126 # introduced by the YUV packing. Accept a maximum 1% mean average error over
127 # the whole frame with no more than 5% of the pixels differing.
128 #
129 compare_frame_fuzzy() {
130         fmt=$(echo $1 | sed 's/M$//')
131         size=$2
132         img_a=$3
133         img_b=$4
134
135         pnm_a=${img_a/bin/pnm}
136         pnm_b=${img_b/bin/pnm}
137
138         raw2rgbpnm -f $fmt -s $size $img_a $pnm_a > /dev/null
139         raw2rgbpnm -f $fmt -s $size $img_b $pnm_b > /dev/null
140
141         ae=$(compare -metric ae $pnm_a $pnm_b /dev/null 2>&1)
142         mae=$(compare -metric mae $pnm_a $pnm_b /dev/null 2>&1 | sed 's/.*(\(.*\))/\1/')
143
144         rm $pnm_a
145         rm $pnm_b
146
147         width=$(echo $size | cut -d 'x' -f 1)
148         height=$(echo $size | cut -d 'x' -f 2)
149
150         ae_match=$(echo $ae $width $height | awk '{ if ($1 / $2 / $3 < 0.05) { print "pass" } else { print "fail" } }')
151         mae_match=$(echo $mae | awk '{ if ($1 < 0.01) { print "pass" } else { print "fail" } }')
152
153         echo "Compared $img_a and $img_b: ae $ae ($ae_match) mae $mae ($mae_match)" | ./logger.sh check >> $logfile
154
155         if [ $ae_match = 'pass' -a $mae_match = 'pass' ] ; then
156                 return 0
157         else
158                 return 1
159         fi
160 }
161
162 compare_frames() {
163         method=$1
164         reftype=$2
165         format=$3
166         wpf=$4
167
168         fmt=$(echo $format | tr '[:upper:]' '[:lower:]')
169         size=$(vsp1_entity_get_size wpf.$wpf 1)
170
171         reference_frame ref-frame.bin $reftype $format $size
172
173         result="pass"
174         for frame in frame-*.bin ; do
175                 (compare_frame_$method $format $size $frame ref-frame.bin) || {
176                         mv $frame ${0/.sh/}-${frame/.bin/-$fmt-$size.bin} ;
177                         result="fail"
178                 }
179         done
180
181         if [ $result = "fail" ] ; then
182                 mv ref-frame.bin ${0/.sh/}-ref-frame-$fmt-$size.bin
183         else
184                 rm -f ref-frame.bin
185         fi
186
187         echo $result
188 }
189
190 compare_histogram() {
191         histo_a=$1
192         histo_b=$2
193
194         match='fail'
195         diff -q $histo_a $histo_b > /dev/null && match='pass'
196
197         echo "Compared $histo_a and $histo_b: $match" | ./logger.sh check >> $logfile
198
199         if [ $match = 'pass' ] ; then
200                 return 0
201         else
202                 return 1
203         fi
204 }
205
206 compare_histograms() {
207         format=$1
208         wpf=$2
209
210         fmt=$(echo $format | tr '[:upper:]' '[:lower:]')
211         size=$(vsp1_entity_get_size wpf.$wpf 1)
212
213         reference_histogram ref-histogram.bin $format $size
214
215         result="pass"
216         for histo in histo-*.bin ; do
217                 (compare_histogram $histo ref-histogram.bin) || {
218                         mv $histo ${0/.sh/}-${histo/.bin/-$fmt.bin} ;
219                         result="fail"
220                 }
221         done
222
223         if [ $result = "fail" ] ; then
224                 mv ref-histogram.bin ${0/.sh/}-ref-histogram-$fmt.bin
225         else
226                 rm -f ref-histogram.bin
227         fi
228
229         echo $result
230 }
231
232 # ------------------------------------------------------------------------------
233 # Pipeline configuration
234 #
235
236 pipe_none() {
237         # Nothing to be done
238         return
239 }
240
241 pipe_rpf_bru() {
242         ninputs=$1
243
244         bru_output=$(vsp1_count_bru_inputs)
245
246         for input in `seq 0 1 $((ninputs-1))` ; do
247                 $mediactl -d $mdev -l "'$dev rpf.$input':1 -> '$dev bru':$input [1]"
248         done
249         $mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev wpf.0':0 [1]"
250         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
251 }
252
253 pipe_rpf_bru_uds() {
254         bru_output=$(vsp1_count_bru_inputs)
255
256         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev bru':0 [1]"
257         $mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev uds.0':0 [1]"
258         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev wpf.0':0 [1]"
259         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
260 }
261
262 pipe_rpf_hgo() {
263         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev wpf.0':0 [1]"
264         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev hgo':0 [1]"
265         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
266 }
267
268 pipe_rpf_uds() {
269         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev uds.0':0 [1]"
270         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev wpf.0':0 [1]"
271         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
272 }
273
274 pipe_rpf_uds_bru() {
275         bru_output=$(vsp1_count_bru_inputs)
276
277         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev uds.0':0 [1]"
278         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev bru':0 [1]"
279         $mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev wpf.0':0 [1]"
280         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
281 }
282
283 pipe_rpf_wpf() {
284         rpf=$1
285         wpf=$2
286
287         $mediactl -d $mdev -l "'$dev rpf.$rpf':1 -> '$dev wpf.$wpf':0 [1]"
288         $mediactl -d $mdev -l "'$dev wpf.$wpf':1 -> '$dev wpf.$wpf output':0 [1]"
289 }
290
291 pipe_reset() {
292         $mediactl -d $mdev -r
293 }
294
295 pipe_configure() {
296         pipe=${1//-/_}
297         shift 1
298
299         pipe_reset
300         pipe_$pipe $*
301 }
302
303 # ------------------------------------------------------------------------------
304 # Format Configuration
305 #
306
307 format_v4l2_to_mbus() {
308         case $1 in
309         RGB332 | ARGB555 | XRGB555 | RGB565 | BGR24 | RGB24 | XBGR32 | XRGB32 | ABGR32 | ARGB32)
310                 echo "ARGB32";
311                 ;;
312
313         NV12M | NV16M | NV21M | NV61M | UYVY | VYUY | YUV420M | YUYV | YVYU)
314                 echo "AYUV32"
315                 ;;
316
317         *)
318                 echo "Invalid format $1" >&2
319                 echo -e "Valid formats are
320 \tRGB332, ARGB555, XRGB555, RGB565, BGR24, RGB24,
321 \tXBGR32, XRGB32, ABGR32, ARGB32,
322 \tNV12M, NV16M, NV21M, NV61M, UYVY, VYUY, YUV420M, YUYV, YVYU" >&2
323                 exit 1
324         esac
325 }
326
327 format_v4l2_is_yuv() {
328         local format=$(format_v4l2_to_mbus $1)
329         [ $format = 'AYUV32' ]
330 }
331
332 format_rpf() {
333         format=$(format_v4l2_to_mbus $1)
334         size=$2
335         rpf=$3
336
337         $mediactl -d $mdev -V "'$dev rpf.$rpf':0 [fmt:$format/$size]"
338 }
339
340 format_rpf_bru() {
341         format=$(format_v4l2_to_mbus $1)
342         size=$2
343         ninputs=$3
344         offset=0
345
346         bru_output=$(vsp1_count_bru_inputs)
347
348         for input in `seq 0 1 $((ninputs-1))` ; do
349                 offset=$((offset+50))
350                 $mediactl -d $mdev -V "'$dev rpf.$input':0 [fmt:$format/$size]"
351                 $mediactl -d $mdev -V "'$dev bru':$input   [fmt:$format/$size compose:($offset,$offset)/$size]"
352         done
353
354         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$format/$size]"
355         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
356         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
357 }
358
359 format_rpf_bru_uds() {
360         infmt=$(format_v4l2_to_mbus $1)
361         insize=$2
362         outfmt=$(format_v4l2_to_mbus $3)
363         outsize=$4
364
365         bru_output=$(vsp1_count_bru_inputs)
366
367         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
368         $mediactl -d $mdev -V "'$dev bru':0 [fmt:$infmt/$insize]"
369         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$infmt/$insize]"
370         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
371         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
372         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
373         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
374 }
375
376 format_rpf_hgo() {
377         format=$(format_v4l2_to_mbus $1)
378         size=$2
379         crop=${3:+crop:$3}
380         compose=${4:+compose:$4}
381
382         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
383         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
384         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
385         $mediactl -d $mdev -V "'$dev hgo':0   [fmt:$format/$size $crop $compose]"
386 }
387
388 format_rpf_uds() {
389         infmt=$(format_v4l2_to_mbus $1)
390         insize=$2
391         outfmt=$(format_v4l2_to_mbus $3)
392         outsize=$4
393
394         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
395         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
396         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
397         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
398         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
399 }
400
401 format_rpf_uds_bru() {
402         infmt=$(format_v4l2_to_mbus $1)
403         insize=$2
404         outfmt=$(format_v4l2_to_mbus $3)
405         outsize=$4
406
407         bru_output=$(vsp1_count_bru_inputs)
408
409         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
410         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
411         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
412         $mediactl -d $mdev -V "'$dev bru':0 [fmt:$infmt/$outsize]"
413         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$infmt/$outsize]"
414         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
415         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
416 }
417
418 format_rpf_wpf() {
419         rpf=$1
420         wpf=$2
421         infmt=$(format_v4l2_to_mbus $3)
422         size=$4
423         outfmt=$(format_v4l2_to_mbus $5)
424         crop=$6
425
426         if [ x$crop != 'x' ] ; then
427                 crop="crop:$crop"
428                 outsize=$(echo $crop | sed 's/.*\///')
429         else
430                 outsize=$size
431         fi
432
433         $mediactl -d $mdev -V "'$dev rpf.$rpf':0 [fmt:$infmt/$size]"
434         $mediactl -d $mdev -V "'$dev wpf.$wpf':0 [fmt:$infmt/$size $crop]"
435         $mediactl -d $mdev -V "'$dev wpf.$wpf':1 [fmt:$outfmt/$outsize]"
436 }
437
438 format_wpf() {
439         format=$(format_v4l2_to_mbus $1)
440         size=$2
441         wpf=$3
442
443         $mediactl -d $mdev -V "'$dev wpf.$wpf':0 [fmt:$format/$size]"
444         $mediactl -d $mdev -V "'$dev wpf.$wpf':1 [fmt:$format/$size]"
445 }
446
447 format_configure() {
448         pipe=${1//-/_}
449         shift 1
450
451         format_$pipe $*
452 }
453
454 # ------------------------------------------------------------------------------
455 # Test run
456 #
457
458 test_init() {
459         logfile=${1/sh/log}
460         features=$2
461
462         rm -f $logfile
463         rm -f *.bin
464
465         for mdev in /dev/media* ; do
466                 match='true'
467                 for feature in $features ; do
468                         $(vsp1_has_feature $feature) || {
469                                 match='false';
470                                 break;
471                         }
472                 done
473
474                 if [ $match == 'true' ] ; then
475                         break
476                 fi
477         done
478
479         if [ $match == 'false' ] ; then
480                 echo "No device found with feature set $features" | ./logger.sh config >> $logfile
481                 exit 1
482         fi
483
484         dev=$(vsp1_device $mdev)
485         echo "Using device $mdev ($dev)" | ./logger.sh config >> $logfile
486
487         vsp_runner=./vsp-runner.sh
488 }
489
490 test_start() {
491         echo "Testing $1" | ./logger.sh >> $logfile
492         echo -n "Testing $1: " >&2
493 }
494
495 test_complete() {
496         echo "Done: $1" | ./logger.sh >> $logfile
497         echo $1 >&2
498
499         rm -f frame-*.bin
500         rm -f histo-*.bin
501 }