Linux USB multiseat audio support

Posted on 20. Jan, 2010 by in udlfb

Here’s how to add audio support on top of the previous instructions for getting USB multiseat running on Linux, with a Plugable UD-160-A type device.

Add the following line to the bottom of the /lib/udev/rules.d/50-usbseat.rules file created per the previous instructions.

KERNEL=="control*", SUBSYSTEM=="sound", SUBSYSTEMS=="usb", PROGRAM="/bin/cat /sys/%p/../../../../../devnum", SYMLINK+="usbseat/%c/sound"

Then create a new /etc/X11/Xsession.d/50usbseat file which will be run at Xsession create time, with the following contents

oldIFS=$IFS
IFS=:
set $DISPLAY
IFS=.
set $2
SEAT_ID=$1
LN=`ls -al /dev/usbseat/$SEAT_ID/sound`
IFS=C
set $LN
CARD_ID=$2
export ALSA_CARD=$2
export ALSA_PCM_CARD=$2
IFS=$oldIFS

Each of the users who might need access to the USB devices needs to be added to the ‘audio’ group. On Ubuntu 9.04, this can be done with these commands to backup and then modify the groups (replace MY_USERNAME, of course) …

sudo cp /etc/group /etc/group_backup
sudo chmod a-wx /etc/group_backup
sudo adduser MY_USERNAME audio

See Ubuntu Sound TroubleShooting for details on that step.

Now, as you connect UD-160-A terminals, a new X instance and GDM login will pop up as before, but also each of them will have /dev/usbseat/%SEAT_ID%/sound linking to their sound device, and the ALSA_CARD environment variable for all processes off of that X session, set to the matching sound card ID. For apps which support ALSA/Pulse (like most browsers, flash, etc.), audio will now come out the correct terminal — all in a completely plug-and-play fashion.

If you’re wondering what the strange IFS stuff is in the above script, it’s bash’s built-in Internal Field Separator variable, which is an easy way to split strings without having to launch a separate sed or awk process.

Note, as before, these instructions are specific to and tested on an older version of Ubuntu: 9.04, and may need to be ported to other distros until the distros themselves integrate these scripts.

Thanks to Alexander Todorov’s earlier work on multiseat sound support, which demonstrated how to match the USB audio devices in udev, and which ALSA_ environment variables to set. Alexander reported some problems reliably matching the audio devices, but with these scripts (with limited testing so far), things are working as expected.

DisplayLink Linux Rotation

Posted on 02. Jan, 2010 by in UGA-2K-A

[updated 8/14/2011 with latest udlfb info]

The xorg generic fbdev driver (xf86-video-fbdev) supports rotation with a custom option (note it disables DGA and xrandr when it rotated mode). DisplayLink devices can use this driver two ways:

  • With the udlfb fb_defio option enabled to detect framebuffer writes based on page faults
  • With the fbdev xorg server patched to report damage (writes to the framebuffer). Instructions for compiling and adding the ReportDamage option to xorg.conf are at the end of this post.

To enable rotation, in the xorg.conf “Device” section, add a Rotate option, setting it to CW, CCW, or UD.

Section "Device"
  Identifier "dl"
  Driver "fbdev"
  Option "rotate" "CCW"
  Option "ReportDamage" "true"
  Option "fbdev" "/dev/fb1"
EndSection

One downside is rendering is significantly slower, as the extra work of rotation is done at the X level and the page-fault behavior of defio means even small updates refresh much of the screen. Here’s some numbers that can be compared to earlier posts (in non-rotate mode):

bernie@bernie-aspireone:~/git/misc-udlfb$ ./udlfb-perf.sh fb0 gtkperf -a
Xlib:  extension "RANDR" missing on display ":3.0".
GtkPerf 0.40 - Starting testing: Fri Jan  1 09:47:20 2010
 
GtkEntry - time:  0.00
GtkComboBox - time:  3.73
GtkComboBoxEntry - time:  2.08
GtkSpinButton - time:  0.49
GtkProgressBar - time:  0.69
GtkToggleButton - time:  0.47
GtkCheckButton - time:  0.44
GtkRadioButton - time:  0.79
GtkTextView - Add text - time:  2.30
GtkTextView - Scroll - time:  1.24
GtkDrawingArea - Lines - time:  4.14
GtkDrawingArea - Circles - time:  4.56
GtkDrawingArea - Text - time:  4.11
GtkDrawingArea - Pixbufs - time:  0.90
 ---
Total time: 25.96
 
Quitting..
 
model name      : Intel(R) Atom(TM) CPU N270   @ 1.60GHz
model name      : Intel(R) Atom(TM) CPU N270   @ 1.60GHz
cpu MHz         : 800.000
cpu MHz         : 800.000
MemTotal:        2052144 kB
Framebuffer Mode: 1920,1080
 
Rendered bytes:  1238913024 (total pixels * Bpp)
Identical bytes: 1070725304 (skipped via shadow buffer check)
sent bytes:      125732225 (compressed usb data, including overhead)
K CPU cycles:    7478653 (transpired, may include context switches)
 
% pixels found to be unchanged: 86.00 %
Compression of changed pixels : 25.00 %
Total CPU cycles spent per input pixel: 6
Total CPU cycles spent per output pixel: 59
USB Mbps: 35.52 (theoretical USB 2.0 peak 480)

DisplayLink Linux performance metrics

Posted on 03. Dec, 2009 by in udlfb

For a USB virtual graphics solution, performance is critical. For the Linux drivers for DisplayLink devices, there are several patches and alternative implementations that are tough to evaluate, compare (and merge) without hard data. It would be great to know what compression ratio we’re getting, how much data is being sent over USB, etc.

So, to enable people to generate that better data, a few lightweight and very low-level benchmarks have been added to udlfb in this patch, which can be grabbed with:

git clone http://git.plugable.com/webdav/udlfb
git checkout origin/sysfs-metrics

What has been added is a set of metrics which are exposed through sysfs. After building branch of the driver with “sudo make install; sudo depmod -a” and a reboot, you’ll find these new files on your system:

ls /sys/class/graphics/fb0/metrics_*
/sys/class/graphics/fb0/metrics_apis_used
/sys/class/graphics/fb0/metrics_bytes_identical
/sys/class/graphics/fb0/metrics_bytes_rendered
/sys/class/graphics/fb0/metrics_bytes_sent
/sys/class/graphics/fb0/metrics_cpu_kcycles_used
/sys/class/graphics/fb0/metrics_reset

If you read any of these files, a request will go down to the udlfb driver, and it will return back the matching metric. One file is write-only: metrics_reset. Writing anything to it will set all the others back to zero.

Sysfs is a really nice mechanism — we can now create some more elaborate test scenarios easily from user mode, and get fairly precise data back from kernel mode.

If you have a working setup of X on top of udlfb (I use this method) — or anything that renders to the framebuffer device — you can now get some much better data about what’s happening in udlfb.

As an example, a script called udlfb-perf.sh has been created to run tests and pretty print a simple report. Here’s the output from a test run on my Acer Aspire laptop running Ubuntu 9.04, using gtkperf as scenario to benchmark.

./udlfb-perf.sh fb0 gtkperf -a
GtkPerf 0.40 - Starting testing: Thu Dec  3 15:16:12 2009
 
GtkEntry - time:  0.00
GtkComboBox - time:  3.17
GtkComboBoxEntry - time:  1.93
GtkSpinButton - time:  0.40
GtkProgressBar - time:  0.60
GtkToggleButton - time:  0.45
GtkCheckButton - time:  0.41
GtkRadioButton - time:  0.74
GtkTextView - Add text - time:  1.99
GtkTextView - Scroll - time:  0.86
GtkDrawingArea - Lines - time:  1.89
GtkDrawingArea - Circles - time:  3.13
GtkDrawingArea - Text - time:  3.05
GtkDrawingArea - Pixbufs - time:  0.56
 --- 
Total time: 19.18
 
Quitting..
 
model name	: Intel(R) Atom(TM) CPU N270   @ 1.60GHz
model name	: Intel(R) Atom(TM) CPU N270   @ 1.60GHz
cpu MHz		: 800.000
cpu MHz		: 800.000
MemTotal:        2052144 kB
Framebuffer Mode: 1920,1080
 
Rendered bytes:  187064790 (total pixels * Bpp)
Identical bytes: 112816894 (skipped via shadow buffer check)
sent bytes:      35556944 (compressed usb data, including overhead)
K CPU cycles:    4316313 (transpired, may include context switches)
 
% pixels found to be unchanged: 60.00 %
Compression of changed pixels : 52.00 %
CPU cycles spent per pixel: 23
USB Mbps: 13.56 (theoretical USB 2.0 peak 480)

To run this, you’ll need the udlfb-perf.sh script (shown below, and also in git here)

And you’ll need gtkperf:

sudo apt-get install gtkperf

Run udlfb-perf on your DisplayLink display, passing it the appropriate framebuffer device (e.g. ./udlfb-perf.sh fb0 gtkperf -a)

#!/bin/bash
# (C) 2009 Bernie Thompson http://plugable.com/
# License http://www.opensource.org/licenses/mit-license.html
 
if [ $# -eq 0 ]
then
    echo
    echo "Usage: $0 fbX [test to benchmark] [test parameters ....]"
    echo "[fbX] must be device visible in /sys/class/graphics directory"
    echo "and should be the DisplayLink device X is currently using"
    echo
    echo "Example: ./udlfb-perf.sh fb0 gtkperf -a"
    echo
    exit 1
fi
 
dev=$1
prog=$2
shift 2
 
echo 1 > /sys/class/graphics/$dev/metrics_reset
 
start=$(date +%s)
$prog $@
end=$(date +%s)
 
rendered=`cat /sys/class/graphics/$dev/metrics_bytes_rendered`
sent=`cat /sys/class/graphics/$dev/metrics_bytes_sent`
identical=`cat /sys/class/graphics/$dev/metrics_bytes_identical`
cycles=`cat /sys/class/graphics/$dev/metrics_cpu_kcycles_used`
mode=`cat /sys/class/graphics/$dev/virtual_size`
 
bus_compress=`/usr/bin/bc <<EOF
scale=2; (($rendered - $identical - $sent) / ($rendered - $identical)) * 100
EOF`
unchanged_pct=`/usr/bin/bc <<EOF
scale=2; (($identical) / $rendered) * 100
EOF`
mbps=`/usr/bin/bc <<EOF
scale=2; ($sent) / ($end - $start) * 8 / 1048576
EOF`
cycles_per_pix=`/usr/bin/bc <<EOF
scale=0; $cycles * 1000 / $rendered
EOF`
 
echo
/bin/grep "model name" /proc/cpuinfo
/bin/grep "MHz" /proc/cpuinfo
/bin/grep "MemTotal" /proc/meminfo
echo "Framebuffer Mode: $mode"
echo
echo "Rendered bytes:  $rendered (total pixels * Bpp)"
echo "Identical bytes: $identical (skipped via shadow buffer check)"
echo "sent bytes:      $sent (compressed usb data, including overhead)"
echo "K CPU cycles:    $cycles (transpired, may include context switches)"
echo
echo "% pixels found to be unchanged: $unchanged_pct %"
echo "Compression of changed pixels : $bus_compress %"
echo "CPU cycles spent per pixel: $cycles_per_pix"
echo "USB Mbps: $mbps (theoretical USB 2.0 peak 480)"
echo

It’d be interesting to see results from other systems and/or some suggested benchmarks other than gtkperf (especially a repeatable video playback test). Please feel free to comment with any of that.

Page 6 of 7« First...34567