Intro
Linux namespaces is the foundation for container-based virtualization, which is becoming increasingly popular. Aside from the ability to isolate a shell (and the processes it generates) from the “main environment”, as is required for this kind of lightweight virtualization, namespaces is useful for overriding selected functionalities.
So I’m jotting down things I use myself.
Using an ad-hoc host name
[root@mycomputer eli]# uname -n
mycomputer.localdomain
[root@mycomputer eli]# unshare -u bash
[root@mycomputer eli]# uname -n
mycomputer.localdomain
[root@mycomputer eli]# hostname newname.localdomain
[root@mycomputer eli]# uname -n
newname.localdomain
[root@mycomputer eli]# exit
[root@mycomputer eli]# uname -n
mycomputer.localdomain
Note that unshare started a new bash shell, with a separate namespace. That’s why hostname’s effect ended when pressing CTRL-D and exiting the shell (where it says “exit”).
The truth is, that “unshare [options] bash” and just “unshare [options]” do the same thing — in the absence of a program to execute, unshare kicks off a new shell.
Hiding the network from a program
Some programs have an annoying “feature” of reporting back (hopefully anonymous) information to its vendor’s server. If it has nothing to do on the internet, it can be run from a subshell that can’t possibly see any network interface. Except for loopback, of course. For example,
# unshare -n bash
# ifconfig lo up
# ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
I should mention that iptables allows rules per user, and there’s always SELinux for those with strong nerves, so these are alternative solutions. But a network namespace looks much simpler to me.
The loopback interface is absent unless enabled as shown above.
In a more sophisticated version, one can add a tunnel interface to the “real world” and apply iptables rules on the dedicated interface. Note that iptables is local to the new network namespace, so it’s empty. The firewall rules can therefore be written inside the network namespace so the main firewall isn’t touched, or rules can be set up on the main firewall for the tunnel interface in the “real world” network namespace.
Root wannabe
It’s possible to be root without being root:
$ unshare -Ur
# whoami
root
# id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)
This is a bluff, of course. The process runs as the original user in reality, but internally, this user is mapped as root. In particular, all files that belong to the original user appear as belonging to root inside this enclosure.
On Linux machines, there’s a command saying
$ xrandr --verbose
which outputs a lot of information about the display, in particular the EDID information obtained from the monitor. Among others, it’s a detailed listing of the video modes that the monitor is willing to accept. These modes are usually the standard VESA graphics modes, but there’s no guarantee that they are. But in reality, they are probably all industry standard, in particular those repeating themselves in the different dumps.
Also in reality, most monitors will display anything thrown at them, as long as it makes sense (or not) even if the graphics mode doesn’t appear on the list. After all, no monitor manufacturer wants the screen to be black when the competitor’s monitor shows as image.
So here are two such dumps. The first one is from my Lenovo Yoga 2 13″ (non-pro) laptop connected to a Dell P2415Q monitor, so the first set of data relates to the laptop’s own screen, and the second set to the much better external monitor (which goes up to UHDTV at 60 fps).
The second set is just my desktop, which is connected to a Samsung 23″ LS23ELDKF (a.k.a LED XL2370HD) monitor.
So the Laptop first:
Screen 0: minimum 320 x 200, current 5760 x 2160, maximum 32767 x 32767
eDP1 connected primary 1920x1080+0+0 (0x47) normal (normal left inverted right x axis y axis) 293mm x 165mm
Identifier: 0x43
Timestamp: 3827058
Subpixel: unknown
Gamma: 1.0:1.0:1.0
Brightness: 1.0
Clones:
CRTC: 0
CRTCs: 0 1 2
Transform: 1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
filter:
EDID:
00ffffffffffff0006af2d2000000000
00160104901d117802bc05a2554c9a25
0e505400000001010101010101010101
0101010101011d3680a070381e403020
8e0025a5100000181d36800872386640
30208e0025a510000018000000fe0041
554f0a202020202020202020000000fe
004231333348414e30322e30200a0043
BACKLIGHT: 94
range: (0, 94)
Backlight: 94
range: (0, 94)
scaling mode: Full aspect
supported: None, Full, Center, Full aspect
Broadcast RGB: Automatic
supported: Automatic, Full, Limited 16:235
audio: auto
supported: force-dvi, off, auto, on
1920x1080 (0x47) 138.5MHz -HSync -VSync *current +preferred
h: width 1920 start 1968 end 2000 total 2080 skew 0 clock 66.6KHz
v: height 1080 start 1088 end 1102 total 1110 clock 60.0Hz
1920x1080 (0xae) 138.5MHz -HSync -VSync
h: width 1920 start 1968 end 2000 total 2440 skew 0 clock 56.8KHz
v: height 1080 start 1088 end 1102 total 1182 clock 48.0Hz
1920x1080 (0xaf) 138.5MHz +HSync -VSync
h: width 1920 start 1968 end 2000 total 2080 skew 0 clock 66.6KHz
v: height 1080 start 1083 end 1088 total 1111 clock 59.9Hz
1680x1050 (0xb0) 146.2MHz -HSync +VSync
h: width 1680 start 1784 end 1960 total 2240 skew 0 clock 65.3KHz
v: height 1050 start 1053 end 1059 total 1089 clock 60.0Hz
1680x1050 (0xb1) 119.0MHz +HSync -VSync
h: width 1680 start 1728 end 1760 total 1840 skew 0 clock 64.7KHz
v: height 1050 start 1053 end 1059 total 1080 clock 59.9Hz
1600x1024 (0xb2) 103.1MHz +HSync +VSync
h: width 1600 start 1600 end 1656 total 1664 skew 0 clock 62.0KHz
v: height 1024 start 1024 end 1029 total 1030 clock 60.2Hz
1400x1050 (0xb3) 122.0MHz +HSync +VSync
h: width 1400 start 1488 end 1640 total 1880 skew 0 clock 64.9KHz
v: height 1050 start 1052 end 1064 total 1082 clock 60.0Hz
1280x1024 (0xb4) 108.0MHz +HSync +VSync
h: width 1280 start 1328 end 1440 total 1688 skew 0 clock 64.0KHz
v: height 1024 start 1025 end 1028 total 1066 clock 60.0Hz
1440x900 (0xb5) 106.5MHz -HSync +VSync
h: width 1440 start 1520 end 1672 total 1904 skew 0 clock 55.9KHz
v: height 900 start 903 end 909 total 934 clock 59.9Hz
1280x960 (0xb6) 108.0MHz +HSync +VSync
h: width 1280 start 1376 end 1488 total 1800 skew 0 clock 60.0KHz
v: height 960 start 961 end 964 total 1000 clock 60.0Hz
1360x768 (0xb7) 84.8MHz -HSync +VSync
h: width 1360 start 1432 end 1568 total 1776 skew 0 clock 47.7KHz
v: height 768 start 771 end 781 total 798 clock 59.8Hz
1360x768 (0xb8) 72.0MHz +HSync -VSync
h: width 1360 start 1408 end 1440 total 1520 skew 0 clock 47.4KHz
v: height 768 start 771 end 781 total 790 clock 60.0Hz
1152x864 (0xb9) 81.6MHz -HSync +VSync
h: width 1152 start 1216 end 1336 total 1520 skew 0 clock 53.7KHz
v: height 864 start 865 end 868 total 895 clock 60.0Hz
1024x768 (0xba) 65.0MHz -HSync -VSync
h: width 1024 start 1048 end 1184 total 1344 skew 0 clock 48.4KHz
v: height 768 start 771 end 777 total 806 clock 60.0Hz
800x600 (0xbb) 40.0MHz +HSync +VSync
h: width 800 start 840 end 968 total 1056 skew 0 clock 37.9KHz
v: height 600 start 601 end 605 total 628 clock 60.3Hz
800x600 (0xbc) 36.0MHz +HSync +VSync
h: width 800 start 824 end 896 total 1024 skew 0 clock 35.2KHz
v: height 600 start 601 end 603 total 625 clock 56.2Hz
640x480 (0xbd) 25.2MHz -HSync -VSync
h: width 640 start 656 end 752 total 800 skew 0 clock 31.5KHz
v: height 480 start 490 end 492 total 525 clock 59.9Hz
HDMI1 connected 3840x2160+1920+0 (0xe3) normal (normal left inverted right x axis y axis) 527mm x 296mm
Identifier: 0x44
Timestamp: 3827058
Subpixel: unknown
Gamma: 1.0:1.0:1.0
Brightness: 1.0
Clones:
CRTC: 1
CRTCs: 0 1 2
Transform: 1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
filter:
EDID:
00ffffffffffff0010acc0a04c553630
2d18010380351e78eae245a8554da326
0b5054a54b00714f8180a9c0a940d1c0
e10001010101a36600a0f0701f803020
35000f282100001a000000ff00503250
43323442343036554c0a000000fc0044
454c4c205032343135510a20000000fd
001d4c1e8c1e000a2020202020200196
02032af15390050402071601141f1213
2720212203061115230907076d030c00
1000303c200060030201023a80187138
2d40582c25000f282100001f011d8018
711c1620582c25000f282100009e0474
0030f2705a80b0588a000f282100001e
565e00a0a0a02950302035000f282100
001a00000000000000000000000000f9
Broadcast RGB: Automatic
supported: Automatic, Full, Limited 16:235
audio: auto
supported: force-dvi, off, auto, on
3840x2160 (0xe3) 262.8MHz +HSync -VSync *current +preferred
h: width 3840 start 3888 end 3920 total 4000 skew 0 clock 65.7KHz
v: height 2160 start 2163 end 2168 total 2191 clock 30.0Hz
3840x2160 (0xe4) 297.0MHz +HSync +VSync
h: width 3840 start 4016 end 4104 total 4400 skew 0 clock 67.5KHz
v: height 2160 start 2168 end 2178 total 2250 clock 30.0Hz
3840x2160 (0xe5) 297.0MHz +HSync +VSync
h: width 3840 start 4896 end 4984 total 5280 skew 0 clock 56.2KHz
v: height 2160 start 2168 end 2178 total 2250 clock 25.0Hz
3840x2160 (0xe6) 297.0MHz +HSync +VSync
h: width 3840 start 5116 end 5204 total 5500 skew 0 clock 54.0KHz
v: height 2160 start 2168 end 2178 total 2250 clock 24.0Hz
3840x2160 (0xe7) 296.7MHz +HSync +VSync
h: width 3840 start 4016 end 4104 total 4400 skew 0 clock 67.4KHz
v: height 2160 start 2168 end 2178 total 2250 clock 30.0Hz
3840x2160 (0xe8) 296.7MHz +HSync +VSync
h: width 3840 start 5116 end 5204 total 5500 skew 0 clock 53.9KHz
v: height 2160 start 2168 end 2178 total 2250 clock 24.0Hz
2560x1440 (0xe9) 241.5MHz +HSync -VSync
h: width 2560 start 2608 end 2640 total 2720 skew 0 clock 88.8KHz
v: height 1440 start 1443 end 1448 total 1481 clock 60.0Hz
2048x1280 (0xea) 221.3MHz -HSync +VSync
h: width 2048 start 2192 end 2416 total 2784 skew 0 clock 79.5KHz
v: height 1280 start 1281 end 1284 total 1325 clock 60.0Hz
1920x1080 (0xeb) 148.5MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.5KHz
v: height 1080 start 1082 end 1087 total 1125 clock 60.0Hz
1920x1080 (0xec) 148.5MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.5KHz
v: height 1080 start 1084 end 1089 total 1125 clock 60.0Hz
1920x1080 (0xed) 148.5MHz +HSync +VSync
h: width 1920 start 2448 end 2492 total 2640 skew 0 clock 56.2KHz
v: height 1080 start 1084 end 1089 total 1125 clock 50.0Hz
1920x1080 (0xee) 148.4MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.4KHz
v: height 1080 start 1084 end 1089 total 1125 clock 59.9Hz
1920x1080i (0xef) 74.2MHz +HSync +VSync Interlace
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 33.8KHz
v: height 1080 start 1084 end 1094 total 1125 clock 60.1Hz
1920x1080i (0xf0) 74.2MHz +HSync +VSync Interlace
h: width 1920 start 2448 end 2492 total 2640 skew 0 clock 28.1KHz
v: height 1080 start 1084 end 1094 total 1125 clock 50.0Hz
1920x1080 (0xf1) 74.2MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 33.8KHz
v: height 1080 start 1084 end 1089 total 1125 clock 30.0Hz
1920x1080 (0xf2) 74.2MHz +HSync +VSync
h: width 1920 start 2448 end 2492 total 2640 skew 0 clock 28.1KHz
v: height 1080 start 1084 end 1089 total 1125 clock 25.0Hz
1920x1080 (0xf3) 74.2MHz +HSync +VSync
h: width 1920 start 2558 end 2602 total 2750 skew 0 clock 27.0KHz
v: height 1080 start 1084 end 1089 total 1125 clock 24.0Hz
1920x1080i (0xf4) 74.2MHz +HSync +VSync Interlace
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 33.7KHz
v: height 1080 start 1084 end 1094 total 1125 clock 60.0Hz
1920x1080 (0xf5) 74.2MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 33.7KHz
v: height 1080 start 1084 end 1089 total 1125 clock 30.0Hz
1920x1080 (0xf6) 74.2MHz +HSync +VSync
h: width 1920 start 2558 end 2602 total 2750 skew 0 clock 27.0KHz
v: height 1080 start 1084 end 1089 total 1125 clock 24.0Hz
1920x1080i (0xf7) 72.0MHz +HSync -VSync Interlace
h: width 1920 start 1952 end 2120 total 2304 skew 0 clock 31.2KHz
v: height 1080 start 1126 end 1136 total 1250 clock 50.0Hz
1600x1200 (0xf8) 162.0MHz +HSync +VSync
h: width 1600 start 1664 end 1856 total 2160 skew 0 clock 75.0KHz
v: height 1200 start 1201 end 1204 total 1250 clock 60.0Hz
1600x900 (0xf9) 119.0MHz -HSync +VSync
h: width 1600 start 1696 end 1864 total 2128 skew 0 clock 55.9KHz
v: height 900 start 901 end 904 total 932 clock 60.0Hz
1280x1024 (0xfa) 135.0MHz +HSync +VSync
h: width 1280 start 1296 end 1440 total 1688 skew 0 clock 80.0KHz
v: height 1024 start 1025 end 1028 total 1066 clock 75.0Hz
1280x1024 (0xb4) 108.0MHz +HSync +VSync
h: width 1280 start 1328 end 1440 total 1688 skew 0 clock 64.0KHz
v: height 1024 start 1025 end 1028 total 1066 clock 60.0Hz
1152x864 (0xfb) 108.0MHz +HSync +VSync
h: width 1152 start 1216 end 1344 total 1600 skew 0 clock 67.5KHz
v: height 864 start 865 end 868 total 900 clock 75.0Hz
1280x720 (0xfc) 74.2MHz +HSync +VSync
h: width 1280 start 1390 end 1430 total 1650 skew 0 clock 45.0KHz
v: height 720 start 725 end 730 total 750 clock 60.0Hz
1280x720 (0xfd) 74.2MHz +HSync +VSync
h: width 1280 start 1720 end 1760 total 1980 skew 0 clock 37.5KHz
v: height 720 start 725 end 730 total 750 clock 50.0Hz
1280x720 (0xfe) 74.2MHz +HSync +VSync
h: width 1280 start 1390 end 1430 total 1650 skew 0 clock 45.0KHz
v: height 720 start 725 end 730 total 750 clock 59.9Hz
1440x576i (0xff) 27.0MHz -HSync -VSync Interlace
h: width 1440 start 1464 end 1590 total 1728 skew 0 clock 15.6KHz
v: height 576 start 580 end 586 total 625 clock 50.1Hz
1024x768 (0x100) 78.8MHz +HSync +VSync
h: width 1024 start 1040 end 1136 total 1312 skew 0 clock 60.1KHz
v: height 768 start 769 end 772 total 800 clock 75.1Hz
1024x768 (0xba) 65.0MHz -HSync -VSync
h: width 1024 start 1048 end 1184 total 1344 skew 0 clock 48.4KHz
v: height 768 start 771 end 777 total 806 clock 60.0Hz
1440x480i (0x101) 27.0MHz -HSync -VSync Interlace
h: width 1440 start 1478 end 1602 total 1716 skew 0 clock 15.8KHz
v: height 480 start 488 end 494 total 525 clock 60.1Hz
1440x480i (0x102) 27.0MHz -HSync -VSync Interlace
h: width 1440 start 1478 end 1602 total 1716 skew 0 clock 15.7KHz
v: height 480 start 488 end 494 total 525 clock 60.1Hz
800x600 (0x103) 49.5MHz +HSync +VSync
h: width 800 start 816 end 896 total 1056 skew 0 clock 46.9KHz
v: height 600 start 601 end 604 total 625 clock 75.0Hz
800x600 (0xbb) 40.0MHz +HSync +VSync
h: width 800 start 840 end 968 total 1056 skew 0 clock 37.9KHz
v: height 600 start 601 end 605 total 628 clock 60.3Hz
720x576 (0x104) 27.0MHz -HSync -VSync
h: width 720 start 732 end 796 total 864 skew 0 clock 31.2KHz
v: height 576 start 581 end 586 total 625 clock 50.0Hz
720x480 (0x105) 27.0MHz -HSync -VSync
h: width 720 start 736 end 798 total 858 skew 0 clock 31.5KHz
v: height 480 start 489 end 495 total 525 clock 60.0Hz
720x480 (0x106) 27.0MHz -HSync -VSync
h: width 720 start 736 end 798 total 858 skew 0 clock 31.5KHz
v: height 480 start 489 end 495 total 525 clock 59.9Hz
640x480 (0x107) 31.5MHz -HSync -VSync
h: width 640 start 656 end 720 total 840 skew 0 clock 37.5KHz
v: height 480 start 481 end 484 total 500 clock 75.0Hz
640x480 (0x108) 25.2MHz -HSync -VSync
h: width 640 start 656 end 752 total 800 skew 0 clock 31.5KHz
v: height 480 start 490 end 492 total 525 clock 60.0Hz
640x480 (0xbd) 25.2MHz -HSync -VSync
h: width 640 start 656 end 752 total 800 skew 0 clock 31.5KHz
v: height 480 start 490 end 492 total 525 clock 59.9Hz
720x400 (0x109) 28.3MHz -HSync +VSync
h: width 720 start 738 end 846 total 900 skew 0 clock 31.5KHz
v: height 400 start 412 end 414 total 449 clock 70.1Hz
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
Identifier: 0x45
Timestamp: 3827058
Subpixel: no subpixels
Clones:
CRTCs: 3
Transform: 1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
filter:
And the Samsung monitor:
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 8192 x 8192
VGA-0 disconnected (normal left inverted right x axis y axis)
Identifier: 0x51
Timestamp: 110079
Subpixel: no subpixels
Clones:
CRTCs: 0 1
Transform: 1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
filter:
load detection: 1 (0x00000001) range: (0,1)
HDMI-0 disconnected (normal left inverted right x axis y axis)
Identifier: 0x52
Timestamp: 110079
Subpixel: horizontal rgb
Clones:
CRTCs: 0 1
Transform: 1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
filter:
audio: off
supported: off on auto
underscan vborder: 0 (0x00000000) range: (0,128)
underscan hborder: 0 (0x00000000) range: (0,128)
underscan: off
supported: off on auto
coherent: 1 (0x00000001) range: (0,1)
DVI-0 connected 1920x1080+0+0 (0x54) normal (normal left inverted right x axis y axis) 510mm x 287mm
Identifier: 0x53
Timestamp: 110079
Subpixel: horizontal rgb
Clones:
CRTC: 0
CRTCs: 0 1
Transform: 1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
filter:
EDID:
00ffffffffffff004c2d2a0733323037
0e14010380331d782a81f1a357539f27
0a5054bfef8081009500b3008140714f
8180a940950f023a801871382d40582c
4500fe1f1100001e000000fd00384b1e
5111000a202020202020000000fc0053
4d584c3233373048440a2020000000ff
004831414b3530303030300a202000a1
load detection: 1 (0x00000001) range: (0,1)
audio: off
supported: off on auto
underscan vborder: 0 (0x00000000) range: (0,128)
underscan hborder: 0 (0x00000000) range: (0,128)
underscan: off
supported: off on auto
coherent: 1 (0x00000001) range: (0,1)
1920x1080 (0x54) 148.5MHz +HSync +VSync *current +preferred
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.5KHz
v: height 1080 start 1084 end 1089 total 1125 clock 60.0Hz
1600x1200 (0x55) 162.0MHz +HSync +VSync
h: width 1600 start 1664 end 1856 total 2160 skew 0 clock 75.0KHz
v: height 1200 start 1201 end 1204 total 1250 clock 60.0Hz
1680x1050 (0x56) 119.0MHz +HSync -VSync
h: width 1680 start 1728 end 1760 total 1840 skew 0 clock 64.7KHz
v: height 1050 start 1053 end 1059 total 1080 clock 59.9Hz
1280x1024 (0x57) 135.0MHz +HSync +VSync
h: width 1280 start 1296 end 1440 total 1688 skew 0 clock 80.0KHz
v: height 1024 start 1025 end 1028 total 1066 clock 75.0Hz
1280x1024 (0x58) 108.0MHz +HSync +VSync
h: width 1280 start 1328 end 1440 total 1688 skew 0 clock 64.0KHz
v: height 1024 start 1025 end 1028 total 1066 clock 60.0Hz
1440x900 (0x59) 136.8MHz -HSync +VSync
h: width 1440 start 1536 end 1688 total 1936 skew 0 clock 70.6KHz
v: height 900 start 903 end 909 total 942 clock 75.0Hz
1440x900 (0x5a) 88.8MHz +HSync -VSync
h: width 1440 start 1488 end 1520 total 1600 skew 0 clock 55.5KHz
v: height 900 start 903 end 909 total 926 clock 59.9Hz
1280x960 (0x5b) 108.0MHz +HSync +VSync
h: width 1280 start 1376 end 1488 total 1800 skew 0 clock 60.0KHz
v: height 960 start 961 end 964 total 1000 clock 60.0Hz
1280x800 (0x5c) 71.0MHz +HSync -VSync
h: width 1280 start 1328 end 1360 total 1440 skew 0 clock 49.3KHz
v: height 800 start 803 end 809 total 823 clock 59.9Hz
1152x864 (0x5d) 108.0MHz +HSync +VSync
h: width 1152 start 1216 end 1344 total 1600 skew 0 clock 67.5KHz
v: height 864 start 865 end 868 total 900 clock 75.0Hz
1024x768 (0x5e) 78.8MHz +HSync +VSync
h: width 1024 start 1040 end 1136 total 1312 skew 0 clock 60.1KHz
v: height 768 start 769 end 772 total 800 clock 75.1Hz
1024x768 (0x5f) 75.0MHz -HSync -VSync
h: width 1024 start 1048 end 1184 total 1328 skew 0 clock 56.5KHz
v: height 768 start 771 end 777 total 806 clock 70.1Hz
1024x768 (0x60) 65.0MHz -HSync -VSync
h: width 1024 start 1048 end 1184 total 1344 skew 0 clock 48.4KHz
v: height 768 start 771 end 777 total 806 clock 60.0Hz
832x624 (0x61) 57.3MHz -HSync -VSync
h: width 832 start 864 end 928 total 1152 skew 0 clock 49.7KHz
v: height 624 start 625 end 628 total 667 clock 74.6Hz
800x600 (0x62) 50.0MHz +HSync +VSync
h: width 800 start 856 end 976 total 1040 skew 0 clock 48.1KHz
v: height 600 start 637 end 643 total 666 clock 72.2Hz
800x600 (0x63) 49.5MHz +HSync +VSync
h: width 800 start 816 end 896 total 1056 skew 0 clock 46.9KHz
v: height 600 start 601 end 604 total 625 clock 75.0Hz
800x600 (0x64) 40.0MHz +HSync +VSync
h: width 800 start 840 end 968 total 1056 skew 0 clock 37.9KHz
v: height 600 start 601 end 605 total 628 clock 60.3Hz
800x600 (0x65) 36.0MHz +HSync +VSync
h: width 800 start 824 end 896 total 1024 skew 0 clock 35.2KHz
v: height 600 start 601 end 603 total 625 clock 56.2Hz
640x480 (0x66) 31.5MHz -HSync -VSync
h: width 640 start 656 end 720 total 840 skew 0 clock 37.5KHz
v: height 480 start 481 end 484 total 500 clock 75.0Hz
640x480 (0x67) 31.5MHz -HSync -VSync
h: width 640 start 664 end 704 total 832 skew 0 clock 37.9KHz
v: height 480 start 489 end 491 total 520 clock 72.8Hz
640x480 (0x68) 30.2MHz -HSync -VSync
h: width 640 start 704 end 768 total 864 skew 0 clock 35.0KHz
v: height 480 start 483 end 486 total 525 clock 66.7Hz
640x480 (0x69) 25.2MHz -HSync -VSync
h: width 640 start 656 end 752 total 800 skew 0 clock 31.5KHz
v: height 480 start 490 end 492 total 525 clock 60.0Hz
720x400 (0x6a) 28.3MHz -HSync +VSync
h: width 720 start 738 end 846 total 900 skew 0 clock 31.5KHz
v: height 400 start 412 end 414 total 449 clock 70.1H
Just in case this is helpful to anyone…
As I implemented a Displayport source (Single Stream Transport, SST) on a Virtex-7 from scratch (based upon GTH outputs), I wrote down some impressions. Here they are, in no particular order.
As for MST (Multiple Stream Transport), which I didn’t touch — I really wonder if someone is going to use it. Or if that part just fills the standard with dead weight.
It’s actually DVI/HDMI over GTX
My personal opinion on the standard is that it’s not so well engineered and poorly written: Some of the mechanisms don’t make much sense (for example, the clock regeneration method), and some are defined quite vaguely. To the extent that it’s likely that an experienced engineer with a good common sense will get it right. But with room for misinterpretations.
Even so, I don’t expect this to prevent Displayport from becoming a long-lived method to connect TVs and monitors to computers and other devices. Odds are that the monitors will ignore much of the possibly ambiguous features in the stream, and work properly, no matter what is thrown on them. The real damage is mainly that it’s harder than necessary to implement the standard on both sides.
The saddest things about this standard is that it didn’t lift off from the classic screen scanning methodology, as the task is merely transmitting pixels data from one side to another. Moving to a GTX-based standard was a great opportunity to leave the old paradigms that date back to the invention of television behind, and adopt digital-age methods. But that didn’t happen.
So instead of just transmitting the image line by line, each line as a packet (like MIPI), the source is required to maintain timing of an imaginary scan of the image, with an imaginary pixel clock, producing a standard VESA graphics mode in terms of active areas and blanking. This is the natural way for a DVI-to-Displayport converter, but when the pixel source is producing Displayport directly, it needs to emulate behavior that goes back to CRT screens.
There is a certain rationale behind this: There might be a Displayport-to-DVI converter on the monitor side, which needs to regenerate the DVI stream, with a pixel clock and horizontal/vertical timings. But this is a transient need. Not something to drag along for years to come.
This isn’t just about difficulty. The need to conform to the timing behavior of some VESA standard forces the source to create blanking periods that it could otherwise skip. The main link is hence forced to be idle a significant part of the time so that an imaginary electron beam of an imaginary CRT screen will have the time to return to the left side.
And there is more: The source is required to throttle the data rate, to make it look as if there’s a pixel source, running on a VESA standard pixel clock, that pushes the pixels. This is done by transmitting stuffing symbols (that is, zero data symbols before scrambling, enclosed by FS and FE control symbols).
To make things even less pleasant, the standard requires that the source to transmit the data in frames of a constant length, Transfer Units (TU). Each transfer unit begins with pixel data, and then switches to stuffing symbols until its end, so that the average pixel rate matches the imaginary pixel clock.
The source can decide on 32-64 symbol clocks for each TU frame. The sink may deduce this length from the positions of the FE control symbols, as this detail isn’t conveyed in another way. One may wonder why the sink would care about the TU’s frame length. And then wonder why it has to be constant.
To make things even worse, the standard doesn’t define how to throttle the data. It doesn’t give any definitive rule on how much the data stream on the symbol stream may be ahead of or behind the imaginary pixel clock that runs continuously. For example, is it OK to bombard the sink with 128 pixels with no throttling in the first TUs, and then slow down? Is it fine to send almost nothing on the first TUs, and then catch up?
It just says things like
…the number of valid data symbols per TU per lane (except for the last TU of a line which may be cut because of the end of active pixel) will be approximated with the following equation:
# of valid data symbols per lane = packed data rate/link symbol rate * TU size
“Approximated”? How much approximated?
and then there’s
The number of valid data symbols per TU will naturally alternate, and over time, the average number will come to the appropriate non-integer value calculated from the above equation
Naturally alternate? How many symbols is a natural alternation?
So even if though the pixel throttling was made for a converter to DVI, it has no guarantee on how much the pixel stream will fluctuate with respect to the pixel clock. It seems like they meant this flactuation to be ±1, but it’s not said. Not a real problem today, given the low price of FIFO memory, but the whole point was to avoid the need of storing the entire line.
Main link implementation shopping list
I found it a bit difficult at first to define what needs to be implemented on the main link, so here’s the shopping list. These are the things that a Displayport source needs to be capable of regarding transmission on the GTX lanes (at a bare minimum, with no audio):
- Three training sequences: TPS1, TPS2 and TPS3 (the last can be omitted if Displayport 1.2 isn’t supported, but it’s not a good idea)
- Pixel data, organized in Transfer Units (TU) of 32-64 symbols each. Each TU must contain stuff symbols (zeros) enclosed by a FS-FE at its end, so that the overall transmission data rate emulates the display mode’s pixel clock. The pixel data itself must be enclosed in Blank End and Blank Start markers, at times replaced by scrambler reset markers.
- Note that as of DisplayPort 1.2, there are six formats for the Blank Start sequence: There’s the enhanced framing sequence which is mandatory for Displayport 1.2, and the non-enhanced version, and the sequences differ for each of the lane configurations (1x, 2x or 4x).
- A scrambler must be implemented to scramble all non-control symbols.
- Once in each Vertical Blank period, the Main Stream Attribute (MSA) Packet must be transmitted once where pixel data would occur otherwise. This is a simple data structure of at most 39 symbols, including the double SS marker in the beginning and the SE at the end, containing the image attributes. It contains, among others, the color coding in the MISC0 field (which is set to 0x20 or 0x21 for plain 24 bpp RGB for asynchronous or synchronous clock, respectively), so it’s not imaginable that a monitor will display something without this information. Someone must have thought that 39 symbols is a huge waste of bandwidth once a frame, so there are (mandatory) shorter versions of this packet for 2 and 4 lane configurations, to make better use of the link. Hurray.
- Per section 5 of the standard, a Displayport source must be able to support both RGB and YCbCr colorimetry formats, with a few bit-per-pixel options at a bare minimum just to support the fallback modes. That may not sound a big deal, but each bit-per-pixel format is packed differently into the symbol streams. On top of that, the source must adapt itself to one of the colorimetry formats that appear in the sink’s EDID information. That doesn’t make life simple, but for practical purposes, I want to see a Displayport monitor that doesn’t support 24 bpp RGB. But that’s not good enough if you’re a graphics card vendor.
The training sequence in short
The training procedure may look quite complicated at first glance, but it merely consists of two stages:
- Clock recovery: The source transmits all symbols as 0x4a data (D10.2) without scrambling, which “happens to be” 8b/10b encoded as a 0101010101 bit sequence. The receiver performs bit clock recovery on this sequence.
- Equalization, word boundary detection and inter-lane deskew: The source transmits a special sequence of symbols without scrambling (TPS2 or TPS3, preferably the latter). The receiver, which knows what to expect, applies its own equalizer (if present) and recovers where a 10-bit symbols starts. When several lanes are used, it also deskews the lanes as required.
One could argue that today’s GTXs don’t need this kind of training, as commonly used equalizers can make up for rather lousy cabling. And it’s not clear if the GTXs actually used are designed to equalize based upon a training sequence.
Anyhow, on each of these two stages, the source runs the following loop: It applies the training sequence on the link, writes to dedicated AUX CH registers to inform the sink what sequence is sent, on which lanes and at what rate, and what gain, pre- and post-emphasis is applied on each lane. The source waits for a known period of time (announced by the sink as TRAINING_AUX_RD_INTERVAL) and then checks the sink’s registers for the status. If the registers indicate success (certain bits set, depending on the phase) the stage of the training is done. If they don’t, other registers will request a new setting of gain, pre- and post-emphasis. The source applies those, and loops again.
The source gives up after four attempts with the same set of gain, pre- and post-emphasis. In other words, if the sink doesn’t change the requests for the signal conditioning four times, it’s a sign it has nothing more to attempt. The source should try to reduce the lane count or rate, and retrain.
When the clock recovery stage is done, the source should go on to equalization without changing the signal conditioning. When the equalization is done, it should exit training and start sending pixels. Needless to say, without changing the signal conditioning.
The control symbols
This is the assignment of control symbols in Verilog. To turn into control symbols, the respective charisk bit must be set in parallel with the codes given below:
assign BS = 8'hbc; // K28.5
assign BE = 8'hfb; // K27.7
assign BF = 8'h7c; // K28.3
assign SR = 8'h1c; // K28.0
assign FS = 8'hfe; // K30.7
assign FE = 8'hf7; // K23.7
assign SS = 8'h5c; // K28.2
assign SE = 8'hfd; // K29.7
Some experiments with a real monitor
Testing my own logic with a Dell P2415Q monitor, I was curious to know what it really cares about in the main link data stream and what it ignores. So here are some insights, which are relevant to this monitor only.
- When lanes are trained properly, but the monitor is unhappy with the data stream, it enters Power Save mode immediately. The display goes out of this mode when the stream is OK.
- Writing 0x01 to DPAUX address 0x600 (attempting to wake it up) should be done after training is done, and video data is present on the link. Not before the training, as this will cause the monitor to remain sleeping.
Things that can be messed with and still get an image:
- Mvid[7:0] on each BS can be set to constant 0. The monitor didn’t care, even though MISC0 was set to asynchronous clocking.
- It had no problem with an arbitrarily large Transfer Unit (including shooting a 1024-pixel wide line in one go)
- Non-enhanced framing mode and enhanced framing mode were both accepted in any mode, even on 5.4 Gbps (which requires enhanced framing).
- There was no problem showing an image on the monitor with scrambling turned off (given that the monitor was informed about this by setting DP AUX register 0x102 to 0x20 instead of 0x00).
The monitor will not display an image without any MSA transmitted. Also, sending an MSA but messing with the following fields prevents displaying the image:
- M (three fields of Mvid)
- The total number of pixels per line, and the total number of lines
- The image’s active area (number of active pixels and rows)
Things that were fine messing in the MSA (image still shown):
- Setting N=0 in async mode is OK, probably because it has to be 32768 anyhow
- All information about the syncs: Position and length
Introduction
The Displayport standard requires the transmission of fields named Mvid in different places of the main link stream, however the relevant parts in the standard are somewhat unclear. This is an attempt to understand the rationale behind the standard’s requirements, in the hope to clarify them.
This post is intended for someone who has spent some time reading the standard. The requirements aren’t listed here, but rather discussed.
Background
Among others, Displayport’s main link is designed to carry a DVI stream transparently as one of the use cases. That is, a DVI-to-Displayport transmitter, which has no particular knowledge of the DVI source, creates the Displayport stream, and a Displayport-to-DVI receiver reconstructs the DVI stream at the other end. This may seem a far-fetched scenario, but if a graphics card vendor wants to support Displayport on a card that only has DVI, a quick solution may be to add such a converter, possibly as a single chip. A monitor vendor may pick a similar solution to support Displayport as well.
Regardless, Displayport is specified to behave as if there was a pixel stream of data arriving with a pixel clock that is slower than the maximal throughput the Displayport link allows. The transmitter is required to pack the data in Transfer Units (TU) of 32-64 symbols length, and fill them partially with data, stuffing the rest of the Transfer Unit with zeros (between FS and FE symbols). The message is clear: Even if a Displayport-aware source has the capability to fetch pixels fast enough to send an entire line continuously on the Displayport link, it’s not the way to go. Instead, imagine that the pixels arrive at a slower pace, and fill each Transfer Unit with a constant number of pixels (plus minus one), so the sink isn’t required to handle pixels faster than necessary. Average the payload, rather than bombard the receiver.
Stream clock recovery
A trickier issue is the stream clock recovery (Stream Clock is the term used in the standard for the pixel clock used by the imaginary or actual DVI pixel stream). As the Displayport-to-DVI converter must present this stream clock on its output as the pixel clock, it needs to maintain some kind of clock PLL. The technically simpler case is when the symbol clock and stream clock are derived from the same reference clock, so the relation between their frequencies is a known constant rational number, which can be conveyed to the receiver. This is referred to as Synchronous Clock Mode in section 2.2.3 of the standard, and defines the PLL dividers M and N for achieving this as
f_stream_clock = f_link_symbol_clock * M / N
But Displayport needs to work when the stream clock is generated by an external source as well. In this Asynchronous Clock Mode the transmitter is required (per section 2.2.3) to measure the frequency approximately by counting the number of clock cycles of the stream clock during a period of 32768 symbol clocks. It should then announce N=32768 and M as the number of clocks counted in the MSA (Main Stream Attribute) packet, transmitted once on each vertical blank period. That makes sense: If the receiver locks a PLL to reconstruct the stream clock based upon M and N and the equation above, it will obtain the stream clock’s frequency within an error of 1/32768 ~ 30.5 ppm, more or less. This is of course unacceptable in the long run, but it’s still a rather small error: At the highest symbol clock of 540 MHz (for 5.4 Gb/s lanes), the 30.5 ppm inaccuracy of the measured M leads to a 16.5 kHz offset. So if the image’s line frequency is 16 kHz (lower than any VESA mode), it’s one pixel clock offset per line.
The Displayport standard allows the required fine-tuning of the receiver’s stream clock by requiring that the 8 LSBs of a stream clock timestamp (Mvid[7:0]) are transmitted at the end of each image line. In other words, the transmitter is required to maintain a free-running counter on its stream clock input, and send the lower bits of its value at the same moment a BS (Blanking Start) control symbol is transmitted on the link (BS marks the end of active pixels in a row, or as a keep-alive in the absence of video data).
The receiver may apply a counter on its own stream clock, and compare the 8 LSBs. As shown above, the difference should be one stream clock at most, so the receiver can fine-tune its PLL to obtain an accurate replica of the transmitter’s stream clock. As real-life clocks aren’t all that stable, and there’s also a chance that spread-spectrum modulation has been applied on the source stream clock, the difference can get bigger than one stream clock. So 8 bits of the timestamp seems to be a good choice.
So far so good. Now to the confusion of notations in the standard.
What’s M?
The main problem is that M is sometimes referred to as a timestamp, and sometimes as a PLL divider. There is a certain similarity, as PLL dividers are counters, and so are timestamps. The difference is that a PLL divider is zeroed when it reaches a certain value, and timestamps are not.
So section 2.2.3 begins with saying
The following equations conceptually explain how the Stream clock (Strm_Clk) must be derived from the Link Symbol clock (LS_Clk) using the Time Stamps, M and N
and uses M and N as dividers immediately after in the equation shown above. It also says a few rows down:
When in Asynchronous Clock mode, the DisplayPort uPacket TX must measure M using a counter running at the LS_Clk frequency as shown in Figure 2-17. The full counter value after every [N x LS_Clk cycles] must be transported in the DisplayPort Main Stream attributes. The least significant eight bits of M (Mvid[7:0]) must be transported once per main video stream horizontal period following BS and VB-ID.
which is a complete mixup. The counter runs on the stream clock and not LS_Clk. Also, [N x LS_Clk cycles] is announced in the MSA in the fields denoted Mvid23:0, Mvid16:8 and Mvid7:0, but these are surely not timestamps, but the result of the count. On the other hand, Mvid[7:0] is a timestamp, and can’t be reset every N symbol clock cycles, as it would be useless for small N’s. In fact, even if N=32768, it’s useless for a 540 MHz symbol clock: For a 33 kHz line frequency, a timestamp reset would occur every second line. So there are two different counters, one is the M divider, and the second the M timestamp, both referred to as Mvid in the standard.
This isn’t all that ambiguous in the Asynchronous Mode case, because the standard says what to do with Mvid in the MSA, and it’s quite obvious that the Mvid[7:0] transmitted along with a BS should be a timestamp that is never reset.
The problem is in Synchronous Mode. The standard doesn’t say what should be transmitted in the MSA. Section 2.2.4, which details the fields, says “M and N for main video stream clock recovery (24 bits each)” showing how the word is split into 3 symbols in drawings. And that’s it. Common sense says that they meant the M and N as PLL dividers. There’s no sense in sending N (denoted Nvid) otherwise. This makes these fields similar to the Asynchronous Mode, and it seems this is the widely accepted interpretation.
Nevertheless, someone out there might as well say the Mvid is Mvid, and it’s the full time stamp counter transmitted on the MSA. The receiver has no other way to know the full word otherwise. One may wonder why it would need it, but that’s a different story. But what is this part in section 2.2.3 good for then, if the full Mvid[23:0] word is never transmitted?
When Mvid7:0 crosses the 8-bit boundary, the entire Mvid23:0 will change. For example, when Mvid23:0 is 000FFFh at one point in time for a given main video stream, the value may turn to 0010000h at another point. The Sink device is responsible for determining the entire Mvid23:0 value based on the updated Mvid7:0.
Maybe the safe choice is to announce Asynchronous Mode regardless of whether the clock ratios are known, hoping that the monitor won’t mess up with the Mvid[7:0] timestamps.
Having said all this, one can speculate that these Mvid and Nvid fields are ignored anyhow by any monitor that has a good reason to support Displayport. Recall that the goal of all this was to reconstruct the stream clock, which doesn’t make sense when Displayport is used for resolutions that DVI can’t support.
Is Mvid[7:0] really required?
This isn’t really about what the standard requires, but the question is why.
Section 2.2.2.1, which details the control symbols for framing, says that BS should be, among others
Inserted at the same symbol time during vertical blanking period as during vertical display
That’s a somewhat odd requirement, as one can’t guarantee a repeated symbol time: In the general case, the streaming clock and symbol clock don’t divide, if they are synchronous at all, and hence the line period in terms of symbol clock can’t be constant.
Not being so picky, it’s clear that the standard requires that the BS is timed closely to some constant position in the originating image’s line. If it can’t hit exactly the same symbol position, move it by one. And since they mention a “same symbol time”, it means that all BS symbols are transmitted like this.
Which in turn means that the number of stream clocks between one BS and another is the total number of pixels per row in the originating image (active pixels + blanking). That number is known through the MSA. So why bother sending Mvid[7:0]? The difference is always the same.
Or maybe the meaning was just that BS has to be bit-aligned in a word the same way as the other symbols? After all, BS is coded as K28.5, which is commonly used as a “comma” symbol that marks the alignment of bits into 10-bit symbols on the wire. But with this interpretation, the requirement is trivial.
Displayport’s standard requires that the TPS2 and TPS3 training sequences have a known running disparity on the transmitted characters. It uses a plus-minus notation (e.g. K28.5-) to indicate the disparity, and also clarifies the meaning of this notation by writing out the bit sequences of K28.5- and K28.5+.
Xilinx, on the other hand, is slightly less definitive: Working with Virtex-7′s GTH, Table 3-6 in UG476 outlines how to set TXCHARDISPVAL to obtain a known disparity, given that TXCHARDISPMODE is ’1′. Unfortunately, the description for TXCHARDISPVAL=0 is “Forces running disparity negative when encoding TXDATA” which is slightly ambiguous. One would expect it to mean that e.g. a K28.5- character would be sent and not a K28.5+, but it could also mean the opposite. Does “forcing running disparity” relate to the history of RD, meaning it would transmit a K28.5+ to make up for the existing cumulative negative running disparity, or does it force the current symbol negative?
I hoped that my Displayport monitor would resolve this by rejecting a training sequence with the disparities flipped, but trying it both ways, it turned out it happily accepted it either way.
So I set up a GTX channel between two FPGAs, one transmitting 8b/10b encoded data, and the second receiving data without 8b/10b decoding. This way I got the actual bits on the wire. I tried loopback first by the way, but it didn’t work out to enable encoding on one direction, and disabling it on the other. Not even by manipulating the Verilog sources that Vivado generated.
Test results
The results of this experiment was as follows:
- With TXCHARDISPVAL = 0, K28.5 is transmitted as 0011111010 on wire.
- With TXCHARDISPVAL = 1, K28.5 is transmitted as 1100000101 on wire.
- And to be sure that the bit polarity isn’t reversed, I verified that D17.1 indeed appears as 1000111001 (it’s indifferent to disparity)
All this relates to TXCHARDISPMODE = 1, of course.
The bit notation here is the bit transmitted first to the left (even though it appears as LSB on the parallel data signals)
Conclusion
TXCHARDISPVAL = 0 = “running disparity negative” = “Current RD -” in Appendix C of UG476. This is also what is referred to as e.g. K28.5- in the Displayport standard.
This is what I expected, as a matter of fact. But I wanted to be sure.
It’s often required to scan a lot of pages in one go, even manually. The problem is that when doing individual scans, there’s a significant delay between each scans, as the computer initializes the scanner for each.
The trick is to use scanimage’s batch scan feature. A typical command for scanning an 10 A4 pages with color into the current directory:
$ scanimage -y 297 --format pnm --batch=scan%04d.pnm --batch-count=10 --resolution 150 --mode Color
Stopping the sequence before the count given (on an HP Officejet 4500 all-in-one) with CTRL-C results in a message saying that the scanning is stopped, and indeed it is. Only the program has to be killed manually, and the scanner unplugged from power, and then powered up again. That aggressive.
Interesting variations:
- For B/W scanning (which is significantly faster), go –mode Gray instead
- The first number used in the file names can be set with –batch-start
- To stop between each scan and wait for the user to press RETURN, add the –batch-prompt flag
Before starting this, it’s recommended to run gthumb on the current directory, so the images can be inspected on the fly:
$ gthumb . &
And after finishing the session, it can be nice to convert the scans to JPG:
$ for i in *.pnm ; do convert $i ${i%%.pnm}.jpg ; done
Even though scanimage –help supplies options that imply that JPEG can be obtained directly from the scanner, it seems like scanimage doesn’t play ball with this.
To convert all pdfs into a jpgs with fairly good resolution (Linux, bash):
for i in *.pdf ; do convert -density 300 "$i" "${i%%.*}.jpg" ; done
Without the -density parameter, the result is pretty lousy.
To prepare a lot of image scans for printing, into a single pdf doc:
convert *.jpg -colorspace gray -contrast-stretch 1% printme.pdf
The contrast stretch is an equalization, so it works well when there’s a full page of stuff. As opposed to a small piece of paper that is scanned.
Just a quick note: The printer was connected via USB, but I sent jobs to it, and nothing happened.
Solution: As root, type hp-setup and flow with the wizard (I unchecked the “fax” part).
As non-root this didn’t work: It failed to install the queue, and asked me to rerun CUPS. But that didn’t help. Only running h-setup as root.
Not clear if this is really useful, but since I’m at it: I killed the Console Kit daemon as root (by process number) and nothing happened except for the following in /var/log/messages:
Apr 14 17:24:52 gnome-session[3378]: WARNING: Could not connect to ConsoleKit: Could not get owner of name 'org.freedesktop.ConsoleKit': no such name
Apr 14 17:24:52 gnome-session[3378]: WARNING: Could not connect to ConsoleKit: Could not get owner of name 'org.freedesktop.ConsoleKit': no such name
Apr 14 17:24:53 gnome-session[3378]: WARNING: Could not connect to ConsoleKit: Could not get owner of name 'org.freedesktop.ConsoleKit': no such name
Apr 14 17:24:54 gnome-session[3378]: WARNING: Could not connect to ConsoleKit: Could not get owner of name 'org.freedesktop.ConsoleKit': no such name
Apr 14 17:24:55 gnome-session[3378]: WARNING: Could not connect to ConsoleKit: Could not get owner of name 'org.freedesktop.ConsoleKit': no such name
That seemed a bit worrying, so I re-enabled it:
# ck-launch-session dbus-launch
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-7yqpBheDeT,guid=77eb3eaa0dca8e1b552d2436cc025ecd
DBUS_SESSION_BUS_PID=26249
And there it’s back again:
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
[...]
root 26177 0.0 0.0 4113796 2820 ? Sl 17:29 0:00 /usr/sbin/console-kit-daemon --no-daemon
And it has a huge Virtual Memory image, which is why I killed it to begin with, thinking it was leaking. So there was no problem to begin with.
Intro
The purpose of this mini-project was to create a video clip with visualized audio, instead of just a dull still frame. Libvisual is the commonly used graphics engine for Linux’ media players, but I wanted the result in a file, not on the screen.
Libvisual’s sources come with lv-tool, which is a command-line utility, apparently for testing the library and its plugins. It may send raw video to standard output, but as of March 2015 there is no plugin for getting the sound from standard input. So I hacked one together, compiled it, and used it with lv-tools (more about this below, of course).
Note to self: To resume, look for libvisual.git in L/linux/.
Installing required packages
The following installations were required on my machine (this may vary, depending on what you already have):
# apt-get install cmake g++
# apt-get install libpng-dev zlib1g-dev
# apt-get install autoconf
# apt-get install liborc-0.4-dev
Downloading & compiling libvisual
$ git clone https://github.com/Libvisual/libvisual.git libvisual
$ git checkout -b myown 4149d9bc1b8277567876ddba1c5415f4d308339d
$ cd libvisual/libvisual
$ cmake .
$ make
$ sudo make install
$ cd ../libvisual-plugins
$ cmake .
$ make
$ sudo make install
There is no particular reason why I checked out that specific commit ID, except a rather random attempt to solve a dependency issue (it was irrelevant, it turned out) and then forgot to switch back.
A trial run (not from stdin yet)
For help:
$ lv-tool -h
Listing plugins
$ lv-tool -p
A test run on a song: In one console, run
$ mplayer -af export=~/.mplayer/mplayer-af_export:512 song.mp3
This plays the song on the computer, and also allows libvisual access to the raw sound samples.
And on another console
$ lv-tool -i mplayer -a blursk -F 300 -f 5 -D 640x480 -d stdout > song.bin
Then play the clip with
$ ffplay -f rawvideo -video_size 640x480 -pix_fmt gray -framerate 5 song.bin
The frame rate was chosen as 5, and it can be increased, of course.
(Use “ffplay -pix_fmts” to get a list of supported pixel format, such as rgb8)
This isn’t all that good, because lv-tool generates video frames on the sound currently played. Even though it’s possible to sync the video with audio later on, there is no guarantee that this sync will remain — if the computer gets busy somewhere in the middle of rendering, lv-tool may stall for a short moment, and then continue with the sound played when it’s back. mplayer won’t wait, and lv-tools will make no effort to compensate for the lost frames — on the contrary, it should skip frames after stalling.
The stdin plugin
The idea behind the stdin plugin is so simple, that I’m quite sure libvisual’s developers actually have written one, but didn’t add it to the distribution to avoid confusion: All it does is reading samples from stdin, and supply a part of them as sound samples for rendering. As the “upload” method is called for every frame, it’s enough to make to consume the amount of sound samples that corresponds to the frame rate that is chosen when the raw video stream is converted into a clip.
The plugin can be added to libvisual’s project tree with this git patch. It’s made against the commit ID mentioned above, but it’s probably fine with later revisions. It doesn’t conform with libvisual’s coding style, I suppose — it’s a hack, after all.
Note that the patch is hardcoded for signed 16 bit, Stereo at 44100 Hz, and produces 30 fps. This is easily modified on the source’s #define statements at the top. The audio samples are supplied to libvisual’s machinery in buffers of 4096 bytes each, even though 44100 x 2 x 2 / 30 = 5880 bytes per frame at 30 fps — it’s common not supply all audio samples that are played. The mplayer plugin supplies only 2048 bytes, for example. This has a minor significance on the graphics.
After patching, re-run cmake, compilation and installation. Instead of reinstalling all, possibly copy the plugin manually into the required directory:
# cp libinput_stdin.so /usr/local/lib/x86_64-linux-gnu/libvisual-0.5/input/
The plugin should appear on “lv-tool -p” after this procedure. And hopefully work too. ;)
Producing video
The blursk actor plugin is assumed here, but any can be used.
First, convert song to WAV:
$ ffmpeg -i song.mp3 song.wav
Note that this is somewhat dirty: I should have requested a raw audio stream with the desired attributes as output, and ffmpeg is capable of doing it. But the common WAV file is more or less that, except for the header, which is skipped quickly enough.
Just make sure the output is stereo, signed 16 bit, 44100 Hz or set ffmpeg’s flags accordingly.
Create graphics (monochrome):
$ lv-tool -i stdin -a blursk -D 640x480 -d stdout > with-stdin.bin < song.wav
Mixing video with audio and creating a DIVX clip:
$ ffmpeg -f rawvideo -s:v 640x480 -pix_fmt gray -r 30 -i with-stdin.bin -ab 128k -b 5000k -i song.wav -vcodec mpeg4 -vtag DIVX try.avi
Same, but with colors (note the -c 32 and -pix_fmt):
$ time lv-tool -i stdin -c 32 -a blursk -D 640x480 -d stdout > color.bin < song.wav
$ ffmpeg -f rawvideo -s:v 640x480 -pix_fmt rgb32 -r 30 -i color.bin -ab 128k -b 5000k -i song.wav -vcodec mpeg4 -vtag DIVX color.avi
It’s also possible to use “24″ instead of “32″ above, but some actors will produce a black screen with this setting. They will also fail the same with 8 bits (grayscale).
And to avoid large intermediate .bin files, pipe from lv-tool to ffmpeg directly:
$ lv-tool -i stdin -c 32 -a blursk -D 640x480 -d stdout < song.wav | ffmpeg -f rawvideo -s:v 640x480 -pix_fmt rgb32 -r 30 -i - -ab 128k -b 5000k -i song.wav -vcodec mpeg4 -vtag DIVX clip.avi
This is handy in particular for high-resolution frames (HD and such).
The try-all script
To scan through all actors in libvisual-0.5, run the following script (produces 720p video, or set “resolution”):
#!/bin/bash
song=$1
resolution=1280x720
for actor in blursk bumpscope corona gforce infinite jakdaw jess \
lv_analyzer lv_scope oinksie plazma ; do
lv-tool -i stdin -c 24 -a $actor -D $resolution -d stdout < $song | \
ffmpeg -f rawvideo -s:v $resolution -pix_fmt rgb24 -r 30 -i - \
-ab 128k -b 5000k -i $song -vcodec mpeg4 -vtag DIVX ${actor}_color.avi
lv-tool -i stdin -c 8 -a $actor -D $resolution -d stdout < $song | \
ffmpeg -f rawvideo -s:v $resolution -pix_fmt gray -r 30 -i - \
-ab 128k -b 5000k -i $song -vcodec mpeg4 -vtag DIVX ${actor}_gray.avi
done
It attempts both color and grayscale.