vsp-lib: Add support for RPF-HST-WPF pipeline
[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/}-$(basename ${frame/.bin/-$params.bin})
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/}-ref-frame-$params.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)
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" >&2
481                 exit 1
482         esac
483 }
484
485 format_v4l2_is_yuv() {
486         local format=$(format_v4l2_to_mbus $1)
487         [ $format = 'AYUV32' ]
488 }
489
490 format_rpf() {
491         local format=$(format_v4l2_to_mbus $1)
492         local size=$2
493         local rpf=$3
494
495         $mediactl -d $mdev -V "'$dev rpf.$rpf':0 [fmt:$format/$size]"
496
497         __vsp_rpf_format=$1
498 }
499
500 format_rpf_bru() {
501         local format=$(format_v4l2_to_mbus $1)
502         local size=$2
503         local ninputs=$3
504         local offset=0
505
506         local bru_output=$(vsp1_count_bru_inputs)
507
508         for input in `seq 0 1 $((ninputs-1))` ; do
509                 offset=$((offset+50))
510                 $mediactl -d $mdev -V "'$dev rpf.$input':0 [fmt:$format/$size]"
511                 $mediactl -d $mdev -V "'$dev bru':$input   [fmt:$format/$size compose:($offset,$offset)/$size]"
512         done
513
514         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$format/$size]"
515         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
516         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
517
518         __vsp_rpf_format=$1
519         __vsp_wpf_format=$1
520 }
521
522 format_rpf_bru_uds() {
523         local infmt=$(format_v4l2_to_mbus $1)
524         local insize=$2
525         local outfmt=$(format_v4l2_to_mbus $3)
526         local outsize=$4
527
528         local bru_output=$(vsp1_count_bru_inputs)
529
530         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
531         $mediactl -d $mdev -V "'$dev bru':0 [fmt:$infmt/$insize]"
532         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$infmt/$insize]"
533         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
534         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
535         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
536         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
537
538         [ $insize != $outsize ] && __vsp_pixel_perfect=false
539         __vsp_rpf_format=$1
540         __vsp_wpf_format=$3
541 }
542
543 format_rpf_clu() {
544         local format=$(format_v4l2_to_mbus $1)
545         local size=$2
546
547         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
548         $mediactl -d $mdev -V "'$dev clu':0 [fmt:$format/$size]"
549         $mediactl -d $mdev -V "'$dev clu':1 [fmt:$format/$size]"
550         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
551         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
552
553         __vsp_rpf_format=$1
554         __vsp_wpf_format=$1
555 }
556
557 format_rpf_hst() {
558         local format=$(format_v4l2_to_mbus $1)
559         local size=$2
560
561         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
562         $mediactl -d $mdev -V "'$dev hst':0 [fmt:$format/$size]"
563         $mediactl -d $mdev -V "'$dev hst':1 [fmt:AHSV8888_1X32/$size]"
564         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:AHSV8888_1X32/$size]"
565         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:AHSV8888_1X32/$size]"
566
567         __vsp_rpf_format=$1
568         __vsp_wpf_format=$3
569 }
570
571 format_rpf_hgo() {
572         local format=$(format_v4l2_to_mbus $1)
573         local size=$2
574         local crop=${3:+crop:$3}
575         local compose=${4:+compose:$4}
576
577         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
578         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
579         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
580         $mediactl -d $mdev -V "'$dev hgo':0   [fmt:$format/$size $crop $compose]"
581
582         __vsp_rpf_format=$1
583         __vsp_wpf_format=$1
584 }
585
586 format_rpf_lut() {
587         local format=$(format_v4l2_to_mbus $1)
588         local size=$2
589
590         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
591         $mediactl -d $mdev -V "'$dev lut':0 [fmt:$format/$size]"
592         $mediactl -d $mdev -V "'$dev lut':1 [fmt:$format/$size]"
593         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
594         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
595
596         __vsp_rpf_format=$1
597         __vsp_wpf_format=$1
598 }
599
600 format_rpf_uds() {
601         local infmt=$(format_v4l2_to_mbus $1)
602         local insize=$2
603         local outfmt=$(format_v4l2_to_mbus $3)
604         local outsize=$4
605
606         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
607         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
608         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
609         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
610         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
611
612         [ $insize != $outsize ] && __vsp_pixel_perfect=false
613         __vsp_rpf_format=$1
614         __vsp_wpf_format=$3
615 }
616
617 format_rpf_uds_bru() {
618         local infmt=$(format_v4l2_to_mbus $1)
619         local insize=$2
620         local outfmt=$(format_v4l2_to_mbus $3)
621         local outsize=$4
622
623         local bru_output=$(vsp1_count_bru_inputs)
624
625         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
626         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
627         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
628         $mediactl -d $mdev -V "'$dev bru':0 [fmt:$infmt/$outsize]"
629         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$infmt/$outsize]"
630         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
631         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
632
633         [ $insize != $outsize ] && __vsp_pixel_perfect=false
634         __vsp_rpf_format=$1
635         __vsp_wpf_format=$3
636 }
637
638 format_rpf_sru() {
639         local infmt=$(format_v4l2_to_mbus $1)
640         local insize=$2
641         local outfmt=$(format_v4l2_to_mbus $3)
642         local outsize=$4
643
644         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
645         $mediactl -d $mdev -V "'$dev sru':0 [fmt:$infmt/$insize]"
646         $mediactl -d $mdev -V "'$dev sru':1 [fmt:$infmt/$outsize]"
647         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
648         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
649
650         __vsp_pixel_perfect=false
651         __vsp_rpf_format=$1
652         __vsp_wpf_format=$3
653 }
654
655 format_rpf_wpf() {
656         local rpf=$1
657         local wpf=$2
658         local infmt=$(format_v4l2_to_mbus $3)
659         local size=$4
660         local outfmt=$(format_v4l2_to_mbus $5)
661         local crop=$6
662         local outsize=
663
664         if [ x$crop != 'x' ] ; then
665                 crop="crop:$crop"
666                 outsize=$(echo $crop | sed 's/.*\///')
667         else
668                 outsize=$size
669         fi
670
671         $mediactl -d $mdev -V "'$dev rpf.$rpf':0 [fmt:$infmt/$size]"
672         $mediactl -d $mdev -V "'$dev wpf.$wpf':0 [fmt:$infmt/$size $crop]"
673         $mediactl -d $mdev -V "'$dev wpf.$wpf':1 [fmt:$outfmt/$outsize]"
674
675         __vsp_rpf_format=$3
676         __vsp_wpf_format=$5
677 }
678
679 format_wpf() {
680         local format=$(format_v4l2_to_mbus $1)
681         local size=$2
682         local wpf=$3
683
684         $mediactl -d $mdev -V "'$dev wpf.$wpf':0 [fmt:$format/$size]"
685         $mediactl -d $mdev -V "'$dev wpf.$wpf':1 [fmt:$format/$size]"
686
687         __vsp_wpf_format=$1
688 }
689
690 format_configure() {
691         local pipe=${1//-/_}
692         shift 1
693
694         format_$pipe $*
695 }
696
697 # ------------------------------------------------------------------------------
698 # Frame capture and output
699 #
700
701 generate_input_frame() {
702         local file=$1
703         local format=$2
704         local size=$3
705
706         local alpha=
707         local options=
708
709         case $format in
710         ARGB555)
711                 alpha=255
712                 ;;
713         ABGR32 | ARGB32)
714                 alpha=200
715                 ;;
716         XRGB555 | XBGR32 | XRGB32)
717                 alpha=0
718                 ;;
719         *)
720                 alpha=255
721                 ;;
722         esac
723
724         $(format_v4l2_is_yuv $format) && options="$options -C -i YUV444M"
725
726         $genimage -f $format -s $size -a $alpha $options -o $file \
727                 frames/frame-reference-1024x768.pnm
728 }
729
730 vsp_runner() {
731         local entity=$1
732         shift
733
734         local option
735         local buffers=4
736         local count=10
737         local pause=
738         local skip=7
739
740         for option in $* ; do
741                 case $option in
742                 --buffers=*)
743                         buffers=${option/--buffers=/}
744                         ;;
745
746                 --count=*)
747                         count=${option/--count=/}
748                         ;;
749
750                 --pause=*)
751                         pause=${option/--pause=/}
752                         ;;
753
754                 --skip=*)
755                         skip=${option/--skip=/}
756                         ;;
757
758                 *)
759                         return 1
760                         ;;
761                 esac
762         done
763
764         local file
765         local videodev
766         local format
767         local size
768
769         case $entity in
770         hgo)
771                 videodev=$(vsp1_entity_subdev "hgo histo")
772                 file="${frames_dir}histo-#.bin"
773                 buffers=10
774                 ;;
775
776         rpf.*)
777                 videodev=$(vsp1_entity_subdev "$entity input")
778                 format=$__vsp_rpf_format
779                 size=$(vsp1_entity_get_size $entity 0)
780                 file=${frames_dir}${entity}.bin
781                 generate_input_frame $file $format $size
782                 ;;
783
784         wpf.*)
785                 videodev=$(vsp1_entity_subdev "$entity output")
786                 format=$__vsp_wpf_format
787                 size=$(vsp1_entity_get_size $entity 1)
788                 file="${frames_dir}frame-#.bin"
789                 ;;
790         esac
791
792         $yavta -c$count -n $buffers ${format:+-f $format} ${size:+-s $size} \
793                 ${skip:+--skip $skip} ${file:+--file=$file} ${pause:+-p$pause} \
794                 $videodev | ./logger.sh $entity >> $logfile
795 }
796
797 vsp_runner_find() {
798         local entity=$1
799         local videodev
800
801         case $entity in
802         hgo)
803                 videodev=$(vsp1_entity_subdev "hgo histo")
804                 ;;
805
806         rpf.*)
807                 videodev=$(vsp1_entity_subdev "$entity input")
808                 ;;
809
810         wpf.*)
811                 videodev=$(vsp1_entity_subdev "$entity output")
812                 ;;
813         esac
814
815         local pid
816
817         for pid in $(pidof yavta) ; do
818                 (ls -l /proc/$pid/fd/ | grep -q "$videodev$") && {
819                         echo $pid ;
820                         break
821                 }
822         done
823 }
824
825 vsp_runner_wait() {
826         local timeout=5
827         local pid
828
829         while [ $timeout != 0 ] ; do
830                 pid=$(vsp_runner_find $1)
831                 [ x$pid != x ] && break
832                 sleep 1
833                 timeout=$((timeout-1))
834         done
835
836         [ x$pid != x ] || return
837
838         while [ ! -f .yavta.wait.$pid ] ; do
839                 sleep 1
840         done
841 }
842
843 vsp_runner_resume() {
844         local pid=$(vsp_runner_find $1)
845
846         [ x$pid != x ] && kill -USR1 $pid
847 }
848
849 # ------------------------------------------------------------------------------
850 # Test run
851 #
852
853 test_init() {
854         export logfile=${1/sh/log}
855         local features=$2
856         local optional_features=$3
857
858         rm -f $logfile
859         rm -f ${1/.sh/}*.bin
860
861         local best_features_count=0
862         local best_mdev=
863
864         for mdev in /dev/media* ; do
865                 dev=$(vsp1_device $mdev)
866
867                 local match='true'
868                 for feature in $features ; do
869                         $(vsp1_has_feature "$feature") || {
870                                 match='false';
871                                 break;
872                         }
873                 done
874
875                 if [ $match == 'false' ] ; then
876                         continue
877                 fi
878
879                 if [ -z "$optional_features" ] ; then
880                         best_mdev=$mdev
881                         break
882                 fi
883
884                 local features_count=0
885                 for feature in $optional_features ; do
886                         $(vsp1_has_feature "$feature") && {
887                                 features_count=$((features_count+1))
888                                 match='false';
889                                 break;
890                         }
891                 done
892
893                 if [ $features_count -ge $best_features_count ] ; then
894                         best_mdev=$mdev
895                         best_features_count=$features_count
896                 fi
897         done
898
899         if [ -z $best_mdev ] ; then
900                 echo "No device found with feature set \`$features'" | ./logger.sh config >> $logfile
901                 echo "Test requires unavailable feature set \`$features': skipped" >&2
902                 exit 1
903         fi
904
905         mdev=$best_mdev
906         dev=$(vsp1_device $mdev)
907         echo "Using device $mdev ($dev)" | ./logger.sh config >> $logfile
908
909         vsp_runner=./vsp-runner.sh
910 }
911
912 test_start() {
913         echo "Testing $1" | ./logger.sh >> $logfile
914         echo -n "Testing $1: " >&2
915 }
916
917 test_complete() {
918         echo "Done: $1" | ./logger.sh >> $logfile
919         echo $1 >&2
920
921         rm -f ${frames_dir}frame-*.bin
922         rm -f ${frames_dir}histo-*.bin
923         rm -f ${frames_dir}rpf.*.bin
924 }
925
926 test_run() {
927         test_main | ./logger.sh error >> $logfile
928 }