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