8f2755b5751903f3df8637811e295cdbb046c6f2
[renesas/vsp-tests.git] / scripts / vsp-lib.sh
1 #!/bin/sh
2
3 genimage='./gen-image'
4 mediactl='media-ctl'
5 yavta='yavta'
6 frames_dir=/tmp/
7
8 # ------------------------------------------------------------------------------
9 # Miscellaneous
10 #
11
12 vsp1_device() {
13         $mediactl -d $mdev -p | grep 'bus info' | sed 's/.*platform://'
14 }
15
16 vsp1_model() {
17         $mediactl -d $mdev -p | grep 'model' | sed 's/.* //'
18 }
19
20 vsp1_generation() {
21         echo $(vsp1_model) | sed 's/-.*//'
22 }
23
24 vsp1_has_feature() {
25         local feature=$1
26         local entity_name=$(echo $feature | sed 's/\[.*//')
27
28         ($mediactl -d $mdev -p | grep -q -- "- entity.*$entity_name") || return
29
30         local option=$(echo $feature | cut -d '[' -f 2 -s | cut -d ']' -f 1)
31
32         [ -z $option ] && return
33
34         local key=$(echo $option | sed 's/:.*//')
35         local value=$(echo $option | sed "s/.*:'\(.*\)'/\1/")
36
37         case $key in
38         control)
39                 vsp1_has_control $entity_name "$value"
40                 return
41                 ;;
42         *)
43                 return 1
44                 ;;
45         esac
46 }
47
48 vsp1_count_rpfs() {
49         $mediactl -d $mdev -p | grep -- '- entity.*rpf.[0-9] [^i]' | wc -l
50 }
51
52 vsp1_count_wpfs() {
53         $mediactl -d $mdev -p | grep -- '- entity.*wpf.[0-9] [^o]' | wc -l
54 }
55
56 vsp1_count_bru_inputs() {
57         local num_pads=`media-ctl -p | grep 'entity.*bru' | sed 's/.*(\([0-9]\) pads.*/\1/'`
58         echo $((num_pads-1))
59 }
60
61 vsp1_entity_subdev() {
62         $mediactl -d $mdev -e "$dev $1"
63 }
64
65 vsp1_entity_get_size() {
66         local entity=$1
67         local pad=$2
68
69         $mediactl -d $mdev --get-v4l2 "'$dev $entity':$pad" | grep fmt | \
70               sed 's/.*\/\([0-9x]*\).*/\1/'
71 }
72
73 vsp1_has_control() {
74         local subdev=$(vsp1_entity_subdev $1)
75         local control_name=$(echo $2 | tr '+' ' ')
76
77         $yavta --no-query -l $subdev | grep -q -- "$control_name"
78 }
79
80 vsp1_set_control() {
81         local entity=$1
82         local control_name=$(echo $2 | tr '+' ' ')
83         local value=$3
84
85         local subdev=$(vsp1_entity_subdev $entity)
86         local control=$($yavta --no-query -l $subdev | grep -- "$control_name" | cut -d ' ' -f 2)
87
88         echo "Setting control $control_name ($control) to $value" | ./logger.sh "$entity" >> $logfile
89         $yavta --no-query -w "$control $value" $subdev | ./logger.sh "$entity" >> $logfile
90 }
91
92 # -----------------------------------------------------------------------------
93 # Referance frame generation
94 #
95
96 reference_frame() {
97         local file=$1
98         local in_format=$2
99         local out_format=$3
100         local size=$4
101         shift 4
102
103         local alpha=
104         local options=
105
106         # Start with the input format to compute the alpha value being used by
107         # the RPF after unpacking. Keep in sync with generate_input_frame.
108         case $in_format in
109         ARGB555)
110                 # The 1-bit alpha value is expanded to 8 bits by copying the
111                 # high order bits, resulting in value of 255 after unpacking.
112                 alpha=255
113                 ;;
114         ABGR32 | ARGB32)
115                 # 8-bit alpha value, hardcoded to 200.
116                 alpha=200
117                 ;;
118         *)
119                 # In all other cases the alpha value is set through a control
120                 # whose default value is 255.
121                 alpha=255
122                 ;;
123         esac
124
125         # Convert the input alpha value based on the output format.
126         case $out_format in
127         ARGB555 | ABGR32 | ARGB32)
128                 # Pass the 8-bit alpha value unchanged to the image generator.
129                 ;;
130         XRGB555)
131                 # The format has the X bit hardcoded to 0.
132                 alpha=0
133                 ;;
134         *)
135                 # In all other cases the alpha value is set through a control
136                 # whose default value is 255.
137                 alpha=255
138                 ;;
139         esac
140
141         local arg
142         for arg in $* ; do
143                 local name=$(echo $arg | cut -d '=' -f 1)
144                 local value=$(echo $arg | cut -d '=' -f 2)
145
146                 case $name in
147                 clu)
148                         options="$options --clu $value"
149                         ;;
150                 hflip)
151                         [ x$value = x1 ] && options="$options --hflip"
152                         ;;
153                 lut)
154                         options="$options --lut $value"
155                         ;;
156                 rotate)
157                         [ x$value = x90 ] && {
158                                 options="$options --rotate" ;
159                                 __vsp_pixel_perfect=false ;
160                         }
161                         ;;
162                 vflip)
163                         [ x$value = x1 ] && options="$options --vflip"
164                         ;;
165                 esac
166         done
167
168         [ x$__vsp_bru_inputs != x ] && options="$options -c $__vsp_bru_inputs"
169
170         $genimage -i $in_format -f $out_format -s $size -a $alpha $options -o $file \
171                 frames/frame-reference-1024x768.pnm
172 }
173
174 reference_histogram() {
175         local file=$1
176         local format=$2
177         local size=$3
178
179         $genimage -i $format -f $format -s $size -H $file \
180                 frames/frame-reference-1024x768.pnm
181 }
182
183 # ------------------------------------------------------------------------------
184 # Image and histogram comparison
185 #
186
187 #
188 # Compare the two frames for exact match.
189 #
190 compare_frame_exact() {
191         local img_a=$3
192         local img_b=$4
193
194         local match='fail'
195         diff -q $img_a $img_b > /dev/null && match='pass'
196
197         echo "Compared $img_a and $img_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 #
207 # Compare the two frames using a fuzzy match algorithm to account for errors
208 # introduced by the YUV packing. Accept a maximum 1% mean average error over
209 # the whole frame with no more than 5% of the pixels differing.
210 #
211 compare_frame_fuzzy() {
212         local fmt=$(echo $1 | sed 's/M$/P/')
213         local size=$2
214         local img_a=$3
215         local img_b=$4
216
217         local pnm_a=${img_a/bin/pnm}
218         local pnm_b=${img_b/bin/pnm}
219
220         raw2rgbpnm -f $fmt -s $size $img_a $pnm_a > /dev/null
221         raw2rgbpnm -f $fmt -s $size $img_b $pnm_b > /dev/null
222
223         local ae=$(compare -metric ae $pnm_a $pnm_b /dev/null 2>&1)
224         local mae=$(compare -metric mae $pnm_a $pnm_b /dev/null 2>&1 | sed 's/.*(\(.*\))/\1/')
225
226         rm $pnm_a
227         rm $pnm_b
228
229         local width=$(echo $size | cut -d 'x' -f 1)
230         local height=$(echo $size | cut -d 'x' -f 2)
231
232         local ae_match=$(echo $ae $width $height | awk '{ if ($1 / $2 / $3 < 0.05) { print "pass" } else { print "fail" } }')
233         local mae_match=$(echo $mae | awk '{ if ($1 < 0.01) { print "pass" } else { print "fail" } }')
234
235         echo "Compared $img_a and $img_b: ae $ae ($ae_match) mae $mae ($mae_match)" | ./logger.sh check >> $logfile
236
237         if [ $ae_match = 'pass' -a $mae_match = 'pass' ] ; then
238                 return 0
239         else
240                 return 1
241         fi
242 }
243
244 compare_frames() {
245         local args=$*
246         local in_format=$__vsp_rpf_format
247         local out_format=$__vsp_wpf_format
248         local wpf=$__vsp_wpf_index
249
250         local in_fmt=$(echo $in_format | tr '[:upper:]' '[:lower:]')
251         local out_fmt=$(echo $out_format | tr '[:upper:]' '[:lower:]')
252         local size=$(vsp1_entity_get_size wpf.$wpf 1)
253
254         reference_frame ${frames_dir}ref-frame.bin $in_format $out_format $size $args
255
256         local method=exact
257         local result="pass"
258         local params=${args// /-}
259         params=${params:+-$params}
260         params=${params//\//_}
261         params=$in_fmt-$out_fmt-$size$params
262
263         if [ x$__vsp_pixel_perfect != xtrue ] ; then
264                 method=fuzzy
265         fi
266
267         for frame in ${frames_dir}frame-*.bin ; do
268                 local match="true"
269
270                 (compare_frame_$method $out_format $size $frame ${frames_dir}ref-frame.bin) ||  {
271                         match="false" ;
272                         result="fail" ;
273                 }
274
275                 if [ $match = "false" -o x$VSP_KEEP_FRAMES = x1 ] ; then
276                         mv $frame ${0/.sh/}-$params-$(basename ${frame})
277                 fi
278         done
279
280         if [ x$VSP_KEEP_FRAMES = x1 -o $result = "fail" ] ; then
281                 mv ${frames_dir}ref-frame.bin ${0/.sh/}-$params-ref-frame.bin
282         else
283                 rm -f ${frames_dir}ref-frame.bin
284                 rm -f ${frames_dir}frame-*.bin
285         fi
286
287         echo $result
288 }
289
290 compare_histogram() {
291         local histo_a=$1
292         local histo_b=$2
293
294         local match='fail'
295         diff -q $histo_a $histo_b > /dev/null && match='pass'
296
297         echo "Compared $histo_a and $histo_b: $match" | ./logger.sh check >> $logfile
298
299         if [ $match = 'pass' ] ; then
300                 return 0
301         else
302                 return 1
303         fi
304 }
305
306 compare_histograms() {
307         local format=$__vsp_wpf_format
308         local wpf=$__vsp_wpf_index
309
310         local fmt=$(echo $format | tr '[:upper:]' '[:lower:]')
311         local size=$(vsp1_entity_get_size wpf.$wpf 1)
312
313         reference_histogram ${frames_dir}ref-histogram.bin $format $size
314
315         local result="pass"
316         for histo in ${frames_dir}histo-*.bin ; do
317                 (compare_histogram $histo ${frames_dir}ref-histogram.bin) || {
318                         mv $histo ${0/.sh/}-$(basename ${histo/.bin/-$fmt.bin}) ;
319                         result="fail"
320                 }
321         done
322
323         if [ $result = "fail" ] ; then
324                 mv ${frames_dir}ref-histogram.bin ${0/.sh/}-ref-histogram-$fmt.bin
325         else
326                 rm -f ${frames_dir}ref-histogram.bin
327                 rm -f ${frames_dir}histo-*.bin
328         fi
329
330         echo $result
331 }
332
333 # ------------------------------------------------------------------------------
334 # Pipeline configuration
335 #
336
337 pipe_none() {
338         # Nothing to be done
339         return
340 }
341
342 pipe_rpf_bru() {
343         local ninputs=$1
344
345         local bru_output=$(vsp1_count_bru_inputs)
346
347         for input in `seq 0 1 $((ninputs-1))` ; do
348                 $mediactl -d $mdev -l "'$dev rpf.$input':1 -> '$dev bru':$input [1]"
349         done
350         $mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev wpf.0':0 [1]"
351         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
352
353         __vsp_bru_inputs=$ninputs
354         __vsp_wpf_index=0
355 }
356
357 pipe_rpf_bru_uds() {
358         local bru_output=$(vsp1_count_bru_inputs)
359
360         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev bru':0 [1]"
361         $mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev uds.0':0 [1]"
362         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev wpf.0':0 [1]"
363         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
364
365         __vsp_wpf_index=0
366 }
367
368 pipe_rpf_clu() {
369         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev clu':0 [1]"
370         $mediactl -d $mdev -l "'$dev clu':1 -> '$dev wpf.0':0 [1]"
371         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
372
373         __vsp_wpf_index=0
374 }
375
376 pipe_rpf_hgo() {
377         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev wpf.0':0 [1]"
378         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev hgo':0 [1]"
379         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
380
381         __vsp_wpf_index=0
382 }
383
384 pipe_rpf_hst() {
385         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev hst':0 [1]"
386         $mediactl -d $mdev -l "'$dev hst':1 -> '$dev wpf.0':0 [1]"
387         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
388
389         __vsp_wpf_index=0
390 }
391
392 pipe_rpf_lut() {
393         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev lut':0 [1]"
394         $mediactl -d $mdev -l "'$dev lut':1 -> '$dev wpf.0':0 [1]"
395         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
396
397         __vsp_wpf_index=0
398 }
399
400 pipe_rpf_uds() {
401         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev uds.0':0 [1]"
402         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev wpf.0':0 [1]"
403         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
404
405         __vsp_wpf_index=0
406 }
407
408 pipe_rpf_uds_bru() {
409         local bru_output=$(vsp1_count_bru_inputs)
410
411         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev uds.0':0 [1]"
412         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev bru':0 [1]"
413         $mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev wpf.0':0 [1]"
414         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
415
416         __vsp_wpf_index=0
417 }
418
419 pipe_rpf_sru() {
420         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev sru':0 [1]"
421         $mediactl -d $mdev -l "'$dev sru':1 -> '$dev wpf.0':0 [1]"
422         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
423
424         __vsp_wpf_index=0
425 }
426
427 pipe_rpf_wpf() {
428         local rpf=$1
429         local wpf=$2
430
431         $mediactl -d $mdev -l "'$dev rpf.$rpf':1 -> '$dev wpf.$wpf':0 [1]"
432         $mediactl -d $mdev -l "'$dev wpf.$wpf':1 -> '$dev wpf.$wpf output':0 [1]"
433
434         __vsp_wpf_index=$wpf
435 }
436
437 pipe_reset() {
438         $mediactl -d $mdev -r
439
440         __vsp_bru_inputs=
441         __vsp_rpf_format=
442         __vsp_wpf_index=
443         __vsp_wpf_format=
444         __vsp_pixel_perfect=true
445 }
446
447 pipe_configure() {
448         local pipe=${1//-/_}
449         shift 1
450
451         pipe_reset
452         pipe_$pipe $*
453 }
454
455 # ------------------------------------------------------------------------------
456 # Format Configuration
457 #
458
459 format_v4l2_to_mbus() {
460         case $1 in
461         RGB332 | ARGB555 | XRGB555 | RGB565 | BGR24 | RGB24 | XBGR32 | XRGB32 | ABGR32 | ARGB32)
462                 echo "ARGB32";
463                 ;;
464
465         HSV24 | HSV32)
466                 echo "AHSV8888_1X32";
467                 ;;
468
469         UYVY | VYUY | YUYV | YVYU | NV12M | NV16M | NV21M | NV61M | YUV420M | YUV422M | YUV444M | YVU420M | YVU422M | YVU444M)
470                 echo "AYUV32"
471                 ;;
472
473         *)
474                 echo "Invalid format $1" >&2
475                 echo -e "Valid formats are
476 \tRGB332, ARGB555, XRGB555, RGB565, BGR24, RGB24,
477 \tXBGR32, XRGB32, ABGR32, ARGB32, HSV24, HSV32
478 \tUYVY, VYUY, YUYV, YVYU,
479 \tNV12M, NV16M, NV21M, NV61M,
480 \tYUV420M, YUV422M, YUV444M,
481 \tYVU420M, YVU422M, YVU444M" >&2
482                 exit 1
483         esac
484 }
485
486 format_v4l2_is_yuv() {
487         local format=$(format_v4l2_to_mbus $1)
488         [ $format = 'AYUV32' ]
489 }
490
491 format_rpf() {
492         local format=$(format_v4l2_to_mbus $1)
493         local size=$2
494         local rpf=$3
495
496         $mediactl -d $mdev -V "'$dev rpf.$rpf':0 [fmt:$format/$size]"
497
498         __vsp_rpf_format=$1
499 }
500
501 format_rpf_bru() {
502         local format=$(format_v4l2_to_mbus $1)
503         local size=$2
504         local ninputs=$3
505         local offset=0
506
507         local bru_output=$(vsp1_count_bru_inputs)
508
509         for input in `seq 0 1 $((ninputs-1))` ; do
510                 offset=$((offset+50))
511                 $mediactl -d $mdev -V "'$dev rpf.$input':0 [fmt:$format/$size]"
512                 $mediactl -d $mdev -V "'$dev bru':$input   [fmt:$format/$size compose:($offset,$offset)/$size]"
513         done
514
515         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$format/$size]"
516         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
517         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
518
519         __vsp_rpf_format=$1
520         __vsp_wpf_format=$1
521 }
522
523 format_rpf_bru_uds() {
524         local infmt=$(format_v4l2_to_mbus $1)
525         local insize=$2
526         local outfmt=$(format_v4l2_to_mbus $3)
527         local outsize=$4
528
529         local bru_output=$(vsp1_count_bru_inputs)
530
531         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
532         $mediactl -d $mdev -V "'$dev bru':0 [fmt:$infmt/$insize]"
533         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$infmt/$insize]"
534         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
535         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
536         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
537         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
538
539         [ $insize != $outsize ] && __vsp_pixel_perfect=false
540         __vsp_rpf_format=$1
541         __vsp_wpf_format=$3
542 }
543
544 format_rpf_clu() {
545         local format=$(format_v4l2_to_mbus $1)
546         local size=$2
547
548         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
549         $mediactl -d $mdev -V "'$dev clu':0 [fmt:$format/$size]"
550         $mediactl -d $mdev -V "'$dev clu':1 [fmt:$format/$size]"
551         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
552         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
553
554         __vsp_rpf_format=$1
555         __vsp_wpf_format=$1
556 }
557
558 format_rpf_hst() {
559         local format=$(format_v4l2_to_mbus $1)
560         local size=$2
561
562         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
563         $mediactl -d $mdev -V "'$dev hst':0 [fmt:$format/$size]"
564         $mediactl -d $mdev -V "'$dev hst':1 [fmt:AHSV8888_1X32/$size]"
565         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:AHSV8888_1X32/$size]"
566         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:AHSV8888_1X32/$size]"
567
568         __vsp_rpf_format=$1
569         __vsp_wpf_format=$3
570 }
571
572 format_rpf_hgo() {
573         local format=$(format_v4l2_to_mbus $1)
574         local size=$2
575         local crop=${3:+crop:$3}
576         local compose=${4:+compose:$4}
577
578         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
579         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
580         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
581         $mediactl -d $mdev -V "'$dev hgo':0   [fmt:$format/$size $crop $compose]"
582
583         __vsp_rpf_format=$1
584         __vsp_wpf_format=$1
585 }
586
587 format_rpf_lut() {
588         local format=$(format_v4l2_to_mbus $1)
589         local size=$2
590
591         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
592         $mediactl -d $mdev -V "'$dev lut':0 [fmt:$format/$size]"
593         $mediactl -d $mdev -V "'$dev lut':1 [fmt:$format/$size]"
594         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
595         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
596
597         __vsp_rpf_format=$1
598         __vsp_wpf_format=$1
599 }
600
601 format_rpf_uds() {
602         local infmt=$(format_v4l2_to_mbus $1)
603         local insize=$2
604         local outfmt=$(format_v4l2_to_mbus $3)
605         local outsize=$4
606
607         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
608         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
609         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
610         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
611         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
612
613         [ $insize != $outsize ] && __vsp_pixel_perfect=false
614         __vsp_rpf_format=$1
615         __vsp_wpf_format=$3
616 }
617
618 format_rpf_uds_bru() {
619         local infmt=$(format_v4l2_to_mbus $1)
620         local insize=$2
621         local outfmt=$(format_v4l2_to_mbus $3)
622         local outsize=$4
623
624         local bru_output=$(vsp1_count_bru_inputs)
625
626         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
627         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
628         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
629         $mediactl -d $mdev -V "'$dev bru':0 [fmt:$infmt/$outsize]"
630         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$infmt/$outsize]"
631         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
632         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
633
634         [ $insize != $outsize ] && __vsp_pixel_perfect=false
635         __vsp_rpf_format=$1
636         __vsp_wpf_format=$3
637 }
638
639 format_rpf_sru() {
640         local infmt=$(format_v4l2_to_mbus $1)
641         local insize=$2
642         local outfmt=$(format_v4l2_to_mbus $3)
643         local outsize=$4
644
645         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
646         $mediactl -d $mdev -V "'$dev sru':0 [fmt:$infmt/$insize]"
647         $mediactl -d $mdev -V "'$dev sru':1 [fmt:$infmt/$outsize]"
648         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
649         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
650
651         __vsp_pixel_perfect=false
652         __vsp_rpf_format=$1
653         __vsp_wpf_format=$3
654 }
655
656 format_rpf_wpf() {
657         local rpf=$1
658         local wpf=$2
659         local infmt=$(format_v4l2_to_mbus $3)
660         local size=$4
661         local outfmt=$(format_v4l2_to_mbus $5)
662         local crop=$6
663         local outsize=
664
665         if [ x$crop != 'x' ] ; then
666                 crop="crop:$crop"
667                 outsize=$(echo $crop | sed 's/.*\///')
668         else
669                 outsize=$size
670         fi
671
672         $mediactl -d $mdev -V "'$dev rpf.$rpf':0 [fmt:$infmt/$size]"
673         $mediactl -d $mdev -V "'$dev wpf.$wpf':0 [fmt:$infmt/$size $crop]"
674         $mediactl -d $mdev -V "'$dev wpf.$wpf':1 [fmt:$outfmt/$outsize]"
675
676         __vsp_rpf_format=$3
677         __vsp_wpf_format=$5
678 }
679
680 format_wpf() {
681         local format=$(format_v4l2_to_mbus $1)
682         local size=$2
683         local wpf=$3
684
685         $mediactl -d $mdev -V "'$dev wpf.$wpf':0 [fmt:$format/$size]"
686         $mediactl -d $mdev -V "'$dev wpf.$wpf':1 [fmt:$format/$size]"
687
688         __vsp_wpf_format=$1
689 }
690
691 format_configure() {
692         local pipe=${1//-/_}
693         shift 1
694
695         format_$pipe $*
696 }
697
698 # ------------------------------------------------------------------------------
699 # Frame capture and output
700 #
701
702 generate_input_frame() {
703         local file=$1
704         local format=$2
705         local size=$3
706
707         local alpha=
708         local options=
709
710         case $format in
711         ARGB555)
712                 alpha=255
713                 ;;
714         ABGR32 | ARGB32)
715                 alpha=200
716                 ;;
717         XRGB555 | XBGR32 | XRGB32)
718                 alpha=0
719                 ;;
720         *)
721                 alpha=255
722                 ;;
723         esac
724
725         $(format_v4l2_is_yuv $format) && options="$options -C -i YUV444M"
726
727         $genimage -f $format -s $size -a $alpha $options -o $file \
728                 frames/frame-reference-1024x768.pnm
729 }
730
731 vsp_runner() {
732         local entity=$1
733         shift
734
735         local option
736         local buffers=4
737         local count=10
738         local pause=
739         local skip=7
740
741         for option in $* ; do
742                 case $option in
743                 --buffers=*)
744                         buffers=${option/--buffers=/}
745                         ;;
746
747                 --count=*)
748                         count=${option/--count=/}
749                         ;;
750
751                 --pause=*)
752                         pause=${option/--pause=/}
753                         ;;
754
755                 --skip=*)
756                         skip=${option/--skip=/}
757                         ;;
758
759                 *)
760                         return 1
761                         ;;
762                 esac
763         done
764
765         local file
766         local videodev
767         local format
768         local size
769
770         case $entity in
771         hgo)
772                 videodev=$(vsp1_entity_subdev "hgo histo")
773                 file="${frames_dir}histo-#.bin"
774                 buffers=10
775                 ;;
776
777         rpf.*)
778                 videodev=$(vsp1_entity_subdev "$entity input")
779                 format=$__vsp_rpf_format
780                 size=$(vsp1_entity_get_size $entity 0)
781                 file=${frames_dir}${entity}.bin
782                 generate_input_frame $file $format $size
783                 ;;
784
785         wpf.*)
786                 videodev=$(vsp1_entity_subdev "$entity output")
787                 format=$__vsp_wpf_format
788                 size=$(vsp1_entity_get_size $entity 1)
789                 file="${frames_dir}frame-#.bin"
790                 ;;
791         esac
792
793         $yavta -c$count -n $buffers ${format:+-f $format} ${size:+-s $size} \
794                 ${skip:+--skip $skip} ${file:+--file=$file} ${pause:+-p$pause} \
795                 $videodev | ./logger.sh $entity >> $logfile
796 }
797
798 vsp_runner_find() {
799         local entity=$1
800         local videodev
801
802         case $entity in
803         hgo)
804                 videodev=$(vsp1_entity_subdev "hgo histo")
805                 ;;
806
807         rpf.*)
808                 videodev=$(vsp1_entity_subdev "$entity input")
809                 ;;
810
811         wpf.*)
812                 videodev=$(vsp1_entity_subdev "$entity output")
813                 ;;
814         esac
815
816         local pid
817
818         for pid in $(pidof yavta) ; do
819                 (ls -l /proc/$pid/fd/ | grep -q "$videodev$") && {
820                         echo $pid ;
821                         break
822                 }
823         done
824 }
825
826 vsp_runner_wait() {
827         local timeout=5
828         local pid
829
830         while [ $timeout != 0 ] ; do
831                 pid=$(vsp_runner_find $1)
832                 [ x$pid != x ] && break
833                 sleep 1
834                 timeout=$((timeout-1))
835         done
836
837         [ x$pid != x ] || return
838
839         while [ ! -f .yavta.wait.$pid ] ; do
840                 sleep 1
841         done
842 }
843
844 vsp_runner_resume() {
845         local pid=$(vsp_runner_find $1)
846
847         [ x$pid != x ] && kill -USR1 $pid
848 }
849
850 # ------------------------------------------------------------------------------
851 # Test run
852 #
853
854 test_init() {
855         export logfile=${1/sh/log}
856         local features=$2
857         local optional_features=$3
858
859         rm -f $logfile
860         rm -f ${1/.sh/}*.bin
861
862         local best_features_count=0
863         local best_mdev=
864
865         for mdev in /dev/media* ; do
866                 dev=$(vsp1_device $mdev)
867
868                 local match='true'
869                 for feature in $features ; do
870                         $(vsp1_has_feature "$feature") || {
871                                 match='false';
872                                 break;
873                         }
874                 done
875
876                 if [ $match == 'false' ] ; then
877                         continue
878                 fi
879
880                 if [ -z "$optional_features" ] ; then
881                         best_mdev=$mdev
882                         break
883                 fi
884
885                 local features_count=0
886                 for feature in $optional_features ; do
887                         $(vsp1_has_feature "$feature") && {
888                                 features_count=$((features_count+1))
889                                 match='false';
890                                 break;
891                         }
892                 done
893
894                 if [ $features_count -ge $best_features_count ] ; then
895                         best_mdev=$mdev
896                         best_features_count=$features_count
897                 fi
898         done
899
900         if [ -z $best_mdev ] ; then
901                 echo "No device found with feature set \`$features'" | ./logger.sh config >> $logfile
902                 echo "Test requires unavailable feature set \`$features': skipped" >&2
903                 exit 1
904         fi
905
906         mdev=$best_mdev
907         dev=$(vsp1_device $mdev)
908         echo "Using device $mdev ($dev)" | ./logger.sh config >> $logfile
909
910         vsp_runner=./vsp-runner.sh
911 }
912
913 test_start() {
914         echo "Testing $1" | ./logger.sh >> $logfile
915         echo -n "Testing $1: " >&2
916 }
917
918 test_complete() {
919         echo "Done: $1" | ./logger.sh >> $logfile
920         echo $1 >&2
921
922         rm -f ${frames_dir}frame-*.bin
923         rm -f ${frames_dir}histo-*.bin
924         rm -f ${frames_dir}rpf.*.bin
925 }
926
927 test_run() {
928         test_main | ./logger.sh error >> $logfile
929 }