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