vsp-lib: Reset controls to defaults on each test run
[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_brx_inputs() {
57         local name=$1
58         local num_pads=`$mediactl -d $mdev -p | grep "entity.*$name" | sed 's/.*(\([0-9]\) pads.*/\1/'`
59         echo $((num_pads-1))
60 }
61
62 vsp1_count_bru_inputs() {
63         __vsp1_count_brx_inputs "bru"
64 }
65
66 vsp1_entity_subdev() {
67         $mediactl -d $mdev -e "$dev $1"
68 }
69
70 vsp1_entity_get_size() {
71         local entity=$1
72         local pad=$2
73
74         $mediactl -d $mdev --get-v4l2 "'$dev $entity':$pad" | grep fmt | \
75               sed 's/.*\/\([0-9x]*\).*/\1/'
76 }
77
78 vsp1_has_control() {
79         local subdev=$(vsp1_entity_subdev $1)
80         local control_name=$(echo $2 | tr '+' ' ')
81
82         $yavta --no-query -l $subdev | grep -q -- "$control_name"
83 }
84
85 vsp1_set_control() {
86         local entity=$1
87         local control_name=$(echo $2 | tr '+' ' ')
88         local value=$3
89
90         local subdev=$(vsp1_entity_subdev $entity)
91         local control=$($yavta --no-query -l $subdev | grep -- "$control_name" | cut -d ' ' -f 2)
92
93         echo "Setting control $control_name ($control) to $value" | ./logger.sh "$entity" >> $logfile
94         $yavta --no-query -w "$control $value" $subdev | ./logger.sh "$entity" >> $logfile
95 }
96
97 vsp1_reset_controls() {
98         local entity=$1
99         local subdev=$(vsp1_entity_subdev $entity)
100
101         echo "Resetting controls on $subdev" | ./logger.sh "$entity" >> $logfile
102         $yavta --no-query --reset-controls $subdev | ./logger.sh "$entity" >> $logfile
103 }
104
105 # -----------------------------------------------------------------------------
106 # Reference frame generation
107 #
108
109 reference_frame() {
110         local file=$1
111         local in_format=$2
112         local out_format=$3
113         local size=$4
114         shift 4
115
116         local alpha=
117         local options=
118
119         # gen-image doesn't support processing HSV input images. The good news
120         # is that the HSV tests that take HSV images as inputs don't need to
121         # perform any processing. We can set the input format to RGB for HSB
122         # reference frame generation.
123         case $in_format in
124         HSV24 | HSV32)
125                 in_format=ARGB32
126                 ;;
127         esac
128
129         # Start with the input format to compute the alpha value being used by
130         # the RPF after unpacking. Keep in sync with generate_input_frame.
131         case $in_format in
132         ARGB555)
133                 # The 1-bit alpha value is expanded to 8 bits by copying the
134                 # high order bits, resulting in value of 255 after unpacking.
135                 alpha=255
136                 ;;
137         ABGR32 | ARGB32)
138                 # 8-bit alpha value, hardcoded to 200.
139                 alpha=200
140                 ;;
141         *)
142                 # In all other cases the alpha value is set through a control
143                 # whose default value is 255.
144                 alpha=255
145                 ;;
146         esac
147
148         # Convert the input alpha value based on the output format.
149         case $out_format in
150         ARGB555 | ABGR32 | ARGB32)
151                 # Pass the 8-bit alpha value unchanged to the image generator.
152                 ;;
153         XRGB555)
154                 # The format has the X bit hardcoded to 0.
155                 alpha=0
156                 ;;
157         *)
158                 # In all other cases the alpha value is set through a control
159                 # whose default value is 255.
160                 alpha=255
161                 ;;
162         esac
163
164         local arg
165         for arg in $* ; do
166                 local name=$(echo $arg | cut -d '=' -f 1)
167                 local value=$(echo $arg | cut -d '=' -f 2)
168
169                 case $name in
170                 clu)
171                         options="$options --clu $value"
172                         ;;
173                 crop)
174                         options="$options --crop $value"
175                         ;;
176                 hflip)
177                         [ x$value = x1 ] && options="$options --hflip"
178                         ;;
179                 lut)
180                         options="$options --lut $value"
181                         ;;
182                 rotate)
183                         [ x$value = x90 ] && {
184                                 options="$options --rotate" ;
185                                 __vsp_pixel_perfect=false ;
186                         }
187                         ;;
188                 vflip)
189                         [ x$value = x1 ] && options="$options --vflip"
190                         ;;
191                 esac
192         done
193
194         [ x$__vsp_brx_inputs != x ] && options="$options -c $__vsp_brx_inputs"
195
196         $genimage -i $in_format -f $out_format -s $size -a $alpha $options -o $file \
197                 frames/frame-reference-1024x768.pnm
198 }
199
200 reference_histogram() {
201         local file=$1
202         local format=$2
203         local size=$3
204         local type=$4
205         local hgt_hue_areas=$5
206
207         local hue=
208         [[ "x$hgt_hue_areas" != x ]] && hue="--histogram-areas $hgt_hue_areas"
209
210         $genimage -i $format -f $format -s $size -H $file --histogram-type $type $hue \
211                 frames/frame-reference-1024x768.pnm
212 }
213
214 # ------------------------------------------------------------------------------
215 # Image and histogram comparison
216 #
217
218 #
219 # Compare the two frames for exact match.
220 #
221 compare_frame_exact() {
222         local img_a=$3
223         local img_b=$4
224
225         local match='fail'
226         diff -q $img_a $img_b > /dev/null && match='pass'
227
228         echo "Compared $img_a and $img_b: $match" | ./logger.sh check >> $logfile
229
230         if [ $match = 'pass' ] ; then
231                 return 0
232         else
233                 return 1
234         fi
235 }
236
237 #
238 # Compare the two frames using a fuzzy match algorithm to account for errors
239 # introduced by the YUV packing. Accept a maximum 1% mean average error over
240 # the whole frame with no more than 5% of the pixels differing.
241 #
242 compare_frame_fuzzy() {
243         local fmt=$(echo $1 | sed 's/M$/P/')
244         local size=$2
245         local img_a=$3
246         local img_b=$4
247
248         local pnm_a=${img_a/bin/pnm}
249         local pnm_b=${img_b/bin/pnm}
250
251         raw2rgbpnm -f $fmt -s $size $img_a $pnm_a > /dev/null
252         raw2rgbpnm -f $fmt -s $size $img_b $pnm_b > /dev/null
253
254         local ae=$(compare -metric ae $pnm_a $pnm_b /dev/null 2>&1)
255         local mae=$(compare -metric mae $pnm_a $pnm_b /dev/null 2>&1 | sed 's/.*(\(.*\))/\1/')
256
257         rm $pnm_a
258         rm $pnm_b
259
260         local width=$(echo $size | cut -d 'x' -f 1)
261         local height=$(echo $size | cut -d 'x' -f 2)
262
263         local ae_match=$(echo $ae $width $height | awk '{ if ($1 / $2 / $3 < 0.05) { print "pass" } else { print "fail" } }')
264         local mae_match=$(echo $mae | awk '{ if ($1 < 0.01) { print "pass" } else { print "fail" } }')
265
266         echo "Compared $img_a and $img_b: ae $ae ($ae_match) mae $mae ($mae_match)" | ./logger.sh check >> $logfile
267
268         if [ $ae_match = 'pass' -a $mae_match = 'pass' ] ; then
269                 return 0
270         else
271                 return 1
272         fi
273 }
274
275 compare_frames() {
276         local args=$*
277         local pipe=$__vsp_pipe
278         local in_format=$__vsp_rpf_format
279         local out_format=$__vsp_wpf_format
280         local wpf=$__vsp_wpf_index
281
282         local in_fmt=$(echo $in_format | tr '[:upper:]' '[:lower:]')
283         local out_fmt=$(echo $out_format | tr '[:upper:]' '[:lower:]')
284         local size=$(vsp1_entity_get_size wpf.$wpf 1)
285
286         reference_frame ${frames_dir}ref-frame.bin $in_format $out_format $size $args
287
288         local method=exact
289         local result="pass"
290         local params=${args// /-}
291         params=${params:+-$params}
292         params=${params//\//_}
293         params=${params//=/_}
294         params=${params//(/_}
295         params=${params//)/_}
296         params=$pipe-$in_fmt-$out_fmt-$size$params
297
298         if [ x$__vsp_pixel_perfect != xtrue ] ; then
299                 method=fuzzy
300         fi
301
302         for frame in ${frames_dir}frame-*.bin ; do
303                 local match="true"
304
305                 (compare_frame_$method $out_format $size $frame ${frames_dir}ref-frame.bin) ||  {
306                         match="false" ;
307                         result="fail" ;
308                 }
309
310                 if [ $match = "false" -o x$VSP_KEEP_FRAMES = x1 ] ; then
311                         mv $frame ${0/.sh/}-$params-$(basename ${frame})
312                 fi
313         done
314
315         if [ x$VSP_KEEP_FRAMES = x1 -o $result = "fail" ] ; then
316                 mv ${frames_dir}ref-frame.bin ${0/.sh/}-$params-ref-frame.bin
317         else
318                 rm -f ${frames_dir}ref-frame.bin
319                 rm -f ${frames_dir}frame-*.bin
320         fi
321
322         echo $result
323 }
324
325 compare_histogram() {
326         local histo_a=$1
327         local histo_b=$2
328
329         local match='fail'
330         diff -q $histo_a $histo_b > /dev/null && match='pass'
331
332         echo "Compared $histo_a and $histo_b: $match" | ./logger.sh check >> $logfile
333
334         if [ $match = 'pass' ] ; then
335                 return 0
336         else
337                 return 1
338         fi
339 }
340
341 compare_histograms() {
342         local hgt_hue_areas=$__vsp_hgt_hue_areas
343         local format=$__vsp_wpf_format
344         local type=$__vsp_histo_type
345         local wpf=$__vsp_wpf_index
346
347         local fmt=$(echo $format | tr '[:upper:]' '[:lower:]')
348         local size=$(vsp1_entity_get_size wpf.$wpf 1)
349
350         reference_histogram ${frames_dir}ref-histogram.bin $format $size $type $hgt_hue_areas
351
352         local result="pass"
353         for histo in ${frames_dir}histo-*.bin ; do
354                 (compare_histogram $histo ${frames_dir}ref-histogram.bin) || {
355                         mv $histo ${0/.sh/}-$(basename ${histo/.bin/-$fmt.bin}) ;
356                         result="fail"
357                 }
358         done
359
360         if [ $result = "fail" ] ; then
361                 mv ${frames_dir}ref-histogram.bin ${0/.sh/}-ref-histogram-$fmt.bin
362         else
363                 rm -f ${frames_dir}ref-histogram.bin
364                 rm -f ${frames_dir}histo-*.bin
365         fi
366
367         echo $result
368 }
369
370 # ------------------------------------------------------------------------------
371 # Pipeline configuration
372 #
373
374 pipe_none() {
375         # Nothing to be done
376         return
377 }
378
379 __pipe_rpf_brx() {
380         local name=$1
381         local ninputs=$2
382
383         local output=$(__vsp1_count_brx_inputs $name)
384
385         for input in `seq 0 1 $((ninputs-1))` ; do
386                 $mediactl -d $mdev -l "'$dev rpf.$input':1 -> '$dev $name':$input [1]"
387         done
388         $mediactl -d $mdev -l "'$dev $name':$output -> '$dev wpf.0':0 [1]"
389         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
390
391         __vsp_brx_inputs=$ninputs
392 }
393
394 pipe_rpf_brs() {
395         __pipe_rpf_brx "brs" $*
396 }
397
398 pipe_rpf_bru() {
399         __pipe_rpf_brx "bru" $*
400 }
401
402 pipe_rpf_bru_uds() {
403         local bru_output=$(vsp1_count_bru_inputs)
404
405         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev bru':0 [1]"
406         $mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev uds.0':0 [1]"
407         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev wpf.0':0 [1]"
408         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
409 }
410
411 pipe_rpf_clu() {
412         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev clu':0 [1]"
413         $mediactl -d $mdev -l "'$dev clu':1 -> '$dev wpf.0':0 [1]"
414         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
415 }
416
417 pipe_rpf_hgo() {
418         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev wpf.0':0 [1]"
419         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev hgo':0 [1]"
420         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
421 }
422
423 pipe_rpf_hst() {
424         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev hst':0 [1]"
425         $mediactl -d $mdev -l "'$dev hst':1 -> '$dev wpf.0':0 [1]"
426         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
427 }
428
429 pipe_rpf_hgt() {
430         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev hst':0 [1]"
431         $mediactl -d $mdev -l "'$dev hst':1 -> '$dev hgt':0 [1]"
432         $mediactl -d $mdev -l "'$dev hst':1 -> '$dev hsi':0 [1]"
433         $mediactl -d $mdev -l "'$dev hsi':1 -> '$dev wpf.0':0 [1]"
434         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
435
436         __vsp_wpf_index=0
437 }
438
439 pipe_rpf_lut() {
440         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev lut':0 [1]"
441         $mediactl -d $mdev -l "'$dev lut':1 -> '$dev wpf.0':0 [1]"
442         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
443 }
444
445 pipe_rpf_uds() {
446         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev uds.0':0 [1]"
447         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev wpf.0':0 [1]"
448         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
449 }
450
451 pipe_rpf_uds_bru() {
452         local bru_output=$(vsp1_count_bru_inputs)
453
454         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev uds.0':0 [1]"
455         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev bru':0 [1]"
456         $mediactl -d $mdev -l "'$dev bru':$bru_output -> '$dev wpf.0':0 [1]"
457         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
458 }
459
460 pipe_rpf_uds_sru() {
461         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev uds.0':0 [1]"
462         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev sru':0 [1]"
463         $mediactl -d $mdev -l "'$dev sru':1 -> '$dev wpf.0':0 [1]"
464         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
465 }
466
467 pipe_rpf_sru() {
468         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev sru':0 [1]"
469         $mediactl -d $mdev -l "'$dev sru':1 -> '$dev wpf.0':0 [1]"
470         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
471 }
472
473 pipe_rpf_sru_uds() {
474         $mediactl -d $mdev -l "'$dev rpf.0':1 -> '$dev sru':0 [1]"
475         $mediactl -d $mdev -l "'$dev sru':1 -> '$dev uds.0':0 [1]"
476         $mediactl -d $mdev -l "'$dev uds.0':1 -> '$dev wpf.0':0 [1]"
477         $mediactl -d $mdev -l "'$dev wpf.0':1 -> '$dev wpf.0 output':0 [1]"
478 }
479
480 pipe_rpf_wpf() {
481         local rpf=$1
482         local wpf=$2
483
484         $mediactl -d $mdev -l "'$dev rpf.$rpf':1 -> '$dev wpf.$wpf':0 [1]"
485         $mediactl -d $mdev -l "'$dev wpf.$wpf':1 -> '$dev wpf.$wpf output':0 [1]"
486
487         __vsp_wpf_index=$wpf
488 }
489
490 pipe_reset() {
491         $mediactl -d $mdev -r
492
493         __vsp_brx_inputs=
494         __vsp_histo_type=
495         __vsp_rpf_format=
496         __vsp_wpf_index=0
497         __vsp_wpf_format=
498         __vsp_pixel_perfect=true
499 }
500
501 pipe_configure() {
502         local pipe=${1//-/_}
503         shift 1
504
505         pipe_reset
506         pipe_$pipe $*
507
508         __vsp_pipe=$pipe
509 }
510
511 # ------------------------------------------------------------------------------
512 # Format Configuration
513 #
514
515 format_v4l2_to_mbus() {
516         case $1 in
517         RGB332 | ARGB555 | XRGB555 | RGB565 | BGR24 | RGB24 | XBGR32 | XRGB32 | ABGR32 | ARGB32)
518                 echo "ARGB32";
519                 ;;
520
521         HSV24 | HSV32)
522                 echo "AHSV8888_1X32";
523                 ;;
524
525         UYVY | VYUY | YUYV | YVYU | NV12M | NV16M | NV21M | NV61M | YUV420M | YUV422M | YUV444M | YVU420M | YVU422M | YVU444M)
526                 echo "AYUV32"
527                 ;;
528
529         *)
530                 echo "Invalid format $1" >&2
531                 echo -e "Valid formats are
532 \tRGB332, ARGB555, XRGB555, RGB565, BGR24, RGB24,
533 \tXBGR32, XRGB32, ABGR32, ARGB32, HSV24, HSV32
534 \tUYVY, VYUY, YUYV, YVYU,
535 \tNV12M, NV16M, NV21M, NV61M,
536 \tYUV420M, YUV422M, YUV444M,
537 \tYVU420M, YVU422M, YVU444M" >&2
538                 exit 1
539         esac
540 }
541
542 format_v4l2_is_yuv() {
543         local format=$(format_v4l2_to_mbus $1)
544         [ $format = 'AYUV32' ]
545 }
546
547 format_rpf() {
548         local format=$(format_v4l2_to_mbus $1)
549         local size=$2
550         local rpf=$3
551
552         $mediactl -d $mdev -V "'$dev rpf.$rpf':0 [fmt:$format/$size]"
553
554         __vsp_rpf_format=$1
555 }
556
557 __format_rpf_brx() {
558         local name=$1
559         local format=$(format_v4l2_to_mbus $2)
560         local size=$3
561         local ninputs=$4
562         local offset=0
563
564         local output=$(__vsp1_count_brx_inputs $name)
565
566         for input in `seq 0 1 $((ninputs-1))` ; do
567                 offset=$((offset+50))
568                 $mediactl -d $mdev -V "'$dev rpf.$input':0 [fmt:$format/$size]"
569                 $mediactl -d $mdev -V "'$dev $name':$input [fmt:$format/$size compose:($offset,$offset)/$size]"
570         done
571
572         $mediactl -d $mdev -V "'$dev $name':$output [fmt:$format/$size]"
573         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
574         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
575
576         __vsp_rpf_format=$2
577         __vsp_wpf_format=$2
578 }
579
580 format_rpf_brs() {
581         __format_rpf_brx "brs" $*
582 }
583
584 format_rpf_bru() {
585         __format_rpf_brx "bru" $*
586 }
587
588 format_rpf_bru_uds() {
589         local infmt=$(format_v4l2_to_mbus $1)
590         local insize=$2
591         local outfmt=$(format_v4l2_to_mbus $3)
592         local outsize=$4
593
594         local bru_output=$(vsp1_count_bru_inputs)
595
596         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
597         $mediactl -d $mdev -V "'$dev bru':0 [fmt:$infmt/$insize]"
598         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$infmt/$insize]"
599         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
600         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
601         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
602         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
603
604         [ $insize != $outsize ] && __vsp_pixel_perfect=false
605         __vsp_rpf_format=$1
606         __vsp_wpf_format=$3
607 }
608
609 format_rpf_clu() {
610         local format=$(format_v4l2_to_mbus $1)
611         local size=$2
612
613         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
614         $mediactl -d $mdev -V "'$dev clu':0 [fmt:$format/$size]"
615         $mediactl -d $mdev -V "'$dev clu':1 [fmt:$format/$size]"
616         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
617         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
618
619         __vsp_rpf_format=$1
620         __vsp_wpf_format=$1
621 }
622
623 format_rpf_hst() {
624         local format=$(format_v4l2_to_mbus $1)
625         local size=$2
626
627         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
628         $mediactl -d $mdev -V "'$dev hst':0 [fmt:$format/$size]"
629         $mediactl -d $mdev -V "'$dev hst':1 [fmt:AHSV8888_1X32/$size]"
630         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:AHSV8888_1X32/$size]"
631         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:AHSV8888_1X32/$size]"
632
633         __vsp_rpf_format=$1
634         __vsp_wpf_format=$3
635 }
636
637 format_rpf_hgo() {
638         local format=$(format_v4l2_to_mbus $1)
639         local size=$2
640         local crop=${3:+crop:$3}
641         local compose=${4:+compose:$4}
642
643         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
644         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
645         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
646         $mediactl -d $mdev -V "'$dev hgo':0   [fmt:$format/$size $crop $compose]"
647
648         __vsp_histo_type=hgo
649         __vsp_rpf_format=$1
650         __vsp_wpf_format=$1
651 }
652
653 format_rpf_hgt() {
654         local format=$(format_v4l2_to_mbus $1)
655         local size=$2
656         local crop=${3:+crop:$3}
657         local compose=${4:+compose:$4}
658
659         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
660         $mediactl -d $mdev -V "'$dev hst':0   [fmt:$format/$size]"
661         $mediactl -d $mdev -V "'$dev hgt':0   [fmt:$format/$size $crop $compose]"
662         $mediactl -d $mdev -V "'$dev hsi':0   [fmt:$format/$size]"
663         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
664         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
665
666         __vsp_histo_type=hgt
667         __vsp_rpf_format=$1
668         __vsp_wpf_format=$1
669 }
670
671 format_rpf_lut() {
672         local format=$(format_v4l2_to_mbus $1)
673         local size=$2
674
675         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$format/$size]"
676         $mediactl -d $mdev -V "'$dev lut':0 [fmt:$format/$size]"
677         $mediactl -d $mdev -V "'$dev lut':1 [fmt:$format/$size]"
678         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$format/$size]"
679         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$format/$size]"
680
681         __vsp_rpf_format=$1
682         __vsp_wpf_format=$1
683 }
684
685 format_rpf_uds() {
686         local infmt=$(format_v4l2_to_mbus $1)
687         local insize=$2
688         local outfmt=$(format_v4l2_to_mbus $3)
689         local outsize=$4
690
691         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
692         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
693         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
694         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
695         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
696
697         [ $insize != $outsize ] && __vsp_pixel_perfect=false
698         __vsp_rpf_format=$1
699         __vsp_wpf_format=$3
700 }
701
702 format_rpf_uds_bru() {
703         local infmt=$(format_v4l2_to_mbus $1)
704         local insize=$2
705         local outfmt=$(format_v4l2_to_mbus $3)
706         local outsize=$4
707
708         local bru_output=$(vsp1_count_bru_inputs)
709
710         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
711         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
712         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
713         $mediactl -d $mdev -V "'$dev bru':0 [fmt:$infmt/$outsize]"
714         $mediactl -d $mdev -V "'$dev bru':$bru_output [fmt:$infmt/$outsize]"
715         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
716         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
717
718         [ $insize != $outsize ] && __vsp_pixel_perfect=false
719         __vsp_rpf_format=$1
720         __vsp_wpf_format=$3
721 }
722
723 format_rpf_uds_sru() {
724         local infmt=$(format_v4l2_to_mbus $1)
725         local insize=$2
726         local midsize=$3
727         local outfmt=$(format_v4l2_to_mbus $4)
728         local outsize=$5
729
730         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
731         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$insize]"
732         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$midsize]"
733         $mediactl -d $mdev -V "'$dev sru':0 [fmt:$infmt/$midsize]"
734         $mediactl -d $mdev -V "'$dev sru':1 [fmt:$infmt/$outsize]"
735         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
736         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
737
738         __vsp_pixel_perfect=false
739         __vsp_rpf_format=$1
740         __vsp_wpf_format=$4
741 }
742
743 format_rpf_sru() {
744         local infmt=$(format_v4l2_to_mbus $1)
745         local insize=$2
746         local outfmt=$(format_v4l2_to_mbus $3)
747         local outsize=$4
748
749         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
750         $mediactl -d $mdev -V "'$dev sru':0 [fmt:$infmt/$insize]"
751         $mediactl -d $mdev -V "'$dev sru':1 [fmt:$infmt/$outsize]"
752         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
753         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
754
755         __vsp_pixel_perfect=false
756         __vsp_rpf_format=$1
757         __vsp_wpf_format=$3
758 }
759
760 format_rpf_sru_uds() {
761         local infmt=$(format_v4l2_to_mbus $1)
762         local insize=$2
763         local midsize=$3
764         local outfmt=$(format_v4l2_to_mbus $4)
765         local outsize=$5
766
767         $mediactl -d $mdev -V "'$dev rpf.0':0 [fmt:$infmt/$insize]"
768         $mediactl -d $mdev -V "'$dev sru':0 [fmt:$infmt/$insize]"
769         $mediactl -d $mdev -V "'$dev sru':1 [fmt:$infmt/$midsize]"
770         $mediactl -d $mdev -V "'$dev uds.0':0 [fmt:$infmt/$midsize]"
771         $mediactl -d $mdev -V "'$dev uds.0':1 [fmt:$infmt/$outsize]"
772         $mediactl -d $mdev -V "'$dev wpf.0':0 [fmt:$infmt/$outsize]"
773         $mediactl -d $mdev -V "'$dev wpf.0':1 [fmt:$outfmt/$outsize]"
774
775         __vsp_pixel_perfect=false
776         __vsp_rpf_format=$1
777         __vsp_wpf_format=$4
778 }
779
780 format_rpf_wpf() {
781         local rpf=$1
782         local wpf=$2
783         local infmt=$(format_v4l2_to_mbus $3)
784         local size=$4
785         local outfmt=$(format_v4l2_to_mbus $5)
786         local rpfcrop=
787         local wpfcrop=
788         local rpfoutsize=
789         local outsize=
790         local option=
791
792         __vsp_rpf_format=$3
793         __vsp_wpf_format=$5
794
795         shift 5
796
797         for option in $* ; do
798                 case $option in
799                 --rpfcrop=*)
800                         rpfcrop=${option/--rpfcrop=/}
801                         ;;
802
803                 --wpfcrop=*)
804                         wpfcrop=${option/--wpfcrop=/}
805                         ;;
806                 *)
807                         echo "format_rpf_wpf: Unrecognised argument $option"
808                         return 1
809                         ;;
810                 esac
811         done
812
813         if [ x$rpfcrop != 'x' ] ; then
814                 rpfcrop="crop:$rpfcrop"
815                 rpfoutsize=$(echo $rpfcrop | sed 's/.*\///')
816         else
817                 rpfoutsize=$size
818         fi
819
820         if [ x$wpfcrop != 'x' ] ; then
821                 wpfcrop="crop:$wpfcrop"
822                 outsize=$(echo $wpfcrop | sed 's/.*\///')
823         else
824                 outsize=$rpfoutsize
825         fi
826
827         $mediactl -d $mdev -V "'$dev rpf.$rpf':0 [fmt:$infmt/$size $rpfcrop]"
828         $mediactl -d $mdev -V "'$dev rpf.$rpf':1 [fmt:$infmt/$rpfoutsize]"
829         $mediactl -d $mdev -V "'$dev wpf.$wpf':0 [fmt:$infmt/$rpfoutsize $wpfcrop]"
830         $mediactl -d $mdev -V "'$dev wpf.$wpf':1 [fmt:$outfmt/$outsize]"
831 }
832
833 format_wpf() {
834         local format=$(format_v4l2_to_mbus $1)
835         local size=$2
836         local wpf=$3
837
838         $mediactl -d $mdev -V "'$dev wpf.$wpf':0 [fmt:$format/$size]"
839         $mediactl -d $mdev -V "'$dev wpf.$wpf':1 [fmt:$format/$size]"
840
841         __vsp_wpf_format=$1
842 }
843
844 format_configure() {
845         local pipe=${1//-/_}
846         shift 1
847
848         format_$pipe $*
849 }
850
851 # ------------------------------------------------------------------------------
852 # Module-specific configuration
853 #
854
855 hgt_configure() {
856         local hue_areas=$1
857
858         vsp1_set_control hgt 'Boundary Values for Hue Area' "{$hue_areas}"
859
860         __vsp_hgt_hue_areas=$hue_areas
861 }
862
863 # ------------------------------------------------------------------------------
864 # Frame capture and output
865 #
866
867 generate_input_frame() {
868         local file=$1
869         local format=$2
870         local size=$3
871
872         local alpha=
873         local options=
874
875         case $format in
876         ARGB555)
877                 alpha=255
878                 ;;
879         ABGR32 | ARGB32)
880                 alpha=200
881                 ;;
882         XRGB555 | XBGR32 | XRGB32)
883                 alpha=0
884                 ;;
885         *)
886                 alpha=255
887                 ;;
888         esac
889
890         $(format_v4l2_is_yuv $format) && options="$options -C -i YUV444M"
891
892         $genimage -f $format -s $size -a $alpha $options -o $file \
893                 frames/frame-reference-1024x768.pnm
894 }
895
896 vsp_runner() {
897         local entity=$1
898         shift
899
900         local option
901         local buffers=4
902         local count=10
903         local pause=
904         local skip=7
905
906         for option in $* ; do
907                 case $option in
908                 --buffers=*)
909                         buffers=${option/--buffers=/}
910                         ;;
911
912                 --count=*)
913                         count=${option/--count=/}
914                         ;;
915
916                 --pause=*)
917                         pause=${option/--pause=/}
918                         ;;
919
920                 --skip=*)
921                         skip=${option/--skip=/}
922                         ;;
923
924                 *)
925                         return 1
926                         ;;
927                 esac
928         done
929
930         local file
931         local videodev
932         local format
933         local size
934
935         case $entity in
936         hgo)
937                 videodev=$(vsp1_entity_subdev "hgo histo")
938                 file="${frames_dir}histo-#.bin"
939                 buffers=10
940                 ;;
941
942         hgt)
943                 videodev=$(vsp1_entity_subdev "hgt histo")
944                 file="${frames_dir}histo-#.bin"
945                 buffers=10
946                 ;;
947
948         rpf.*)
949                 videodev=$(vsp1_entity_subdev "$entity input")
950                 format=$__vsp_rpf_format
951                 size=$(vsp1_entity_get_size $entity 0)
952                 file=${frames_dir}${entity}.bin
953                 generate_input_frame $file $format $size
954                 ;;
955
956         wpf.*)
957                 videodev=$(vsp1_entity_subdev "$entity output")
958                 format=$__vsp_wpf_format
959                 size=$(vsp1_entity_get_size $entity 1)
960                 file="${frames_dir}frame-#.bin"
961                 ;;
962         esac
963
964         $yavta -c$count -n $buffers ${format:+-f $format} ${size:+-s $size} \
965                 ${skip:+--skip $skip} ${file:+--file=$file} ${pause:+-p$pause} \
966                 $videodev | ./logger.sh $entity >> $logfile
967 }
968
969 vsp_runner_find() {
970         local entity=$1
971         local videodev
972
973         case $entity in
974         hgo)
975                 videodev=$(vsp1_entity_subdev "hgo histo")
976                 ;;
977
978         hgt)
979                 videodev=$(vsp1_entity_subdev "hgt histo")
980                 ;;
981
982         rpf.*)
983                 videodev=$(vsp1_entity_subdev "$entity input")
984                 ;;
985
986         wpf.*)
987                 videodev=$(vsp1_entity_subdev "$entity output")
988                 ;;
989         esac
990
991         local pid
992
993         for pid in $(pidof yavta) ; do
994                 (ls -l /proc/$pid/fd/ | grep -q "$videodev$") && {
995                         echo $pid ;
996                         break
997                 }
998         done
999 }
1000
1001 vsp_runner_wait() {
1002         local timeout=5
1003         local pid
1004
1005         while [ $timeout != 0 ] ; do
1006                 pid=$(vsp_runner_find $1)
1007                 [ x$pid != x ] && break
1008                 sleep 1
1009                 timeout=$((timeout-1))
1010         done
1011
1012         [ x$pid != x ] || return
1013
1014         while [ ! -f .yavta.wait.$pid ] ; do
1015                 sleep 1
1016         done
1017 }
1018
1019 vsp_runner_resume() {
1020         local pid=$(vsp_runner_find $1)
1021
1022         [ x$pid != x ] && kill -USR1 $pid
1023 }
1024
1025 # ------------------------------------------------------------------------------
1026 # Test run
1027 #
1028
1029 test_init() {
1030         export logfile=${1/sh/log}
1031         local features=$2
1032         local optional_features=$3
1033
1034         rm -f $logfile
1035         rm -f ${1/.sh/}*.bin
1036
1037         local best_features_count=0
1038         local best_mdev=
1039
1040         for mdev in /dev/media* ; do
1041                 dev=$(vsp1_device $mdev)
1042
1043                 local match='true'
1044                 for feature in $features ; do
1045                         $(vsp1_has_feature "$feature") || {
1046                                 match='false';
1047                                 break;
1048                         }
1049                 done
1050
1051                 if [ $match == 'false' ] ; then
1052                         continue
1053                 fi
1054
1055                 if [ -z "$optional_features" ] ; then
1056                         best_mdev=$mdev
1057                         break
1058                 fi
1059
1060                 local features_count=0
1061                 for feature in $optional_features ; do
1062                         $(vsp1_has_feature "$feature") && {
1063                                 features_count=$((features_count+1))
1064                                 match='false';
1065                                 break;
1066                         }
1067                 done
1068
1069                 if [ $features_count -ge $best_features_count ] ; then
1070                         best_mdev=$mdev
1071                         best_features_count=$features_count
1072                 fi
1073         done
1074
1075         if [ -z $best_mdev ] ; then
1076                 echo "No device found with feature set \`$features'" | ./logger.sh config >> $logfile
1077                 echo "Test requires unavailable feature set \`$features': skipped" >&2
1078                 exit 1
1079         fi
1080
1081         mdev=$best_mdev
1082         dev=$(vsp1_device $mdev)
1083         echo "Using device $mdev ($dev)" | ./logger.sh config >> $logfile
1084
1085         # Reset any rotation or flipping controls
1086         vsp1_reset_controls wpf.0
1087
1088         vsp_runner=./vsp-runner.sh
1089 }
1090
1091 test_start() {
1092         echo "Testing $1" | ./logger.sh >> $logfile
1093         echo -n "Testing $1: " >&2
1094
1095         # Store the marker for the last line of the kernel log.
1096         marker=$(dmesg | tail -n 1 | sed 's/^\[\([^]]*\)\].*/\1/g')
1097 }
1098
1099 test_complete() {
1100         echo "Done: $1" | ./logger.sh >> $logfile
1101         echo $1 >&2
1102
1103         # Capture the part of the kernel log relative to the test.
1104         dmesg | sed "1,/$marker/d" | ./logger.sh kernel >> $logfile
1105
1106         rm -f ${frames_dir}frame-*.bin
1107         rm -f ${frames_dir}histo-*.bin
1108         rm -f ${frames_dir}rpf.*.bin
1109 }
1110
1111 test_run() {
1112         test_main | ./logger.sh error >> $logfile
1113 }