Linuxové ovladače TV karet vytvářejí s pomocí udev své virtuální soubory v adresáři /dev
– analogové TV karty pod názvem /dev/videoX
(kde X je postupně rostoucí číslo od 0 v pořadí, jak jsou karty detekovány) a digitální TV karty pod názvem /dev/dvb/adapterX/
(X opět roste od 0 v pořadí detekování karet). V konfiguraci mythbackendu se zadávají a rozlišují jednotlivé TV karty právě touto cestou, takže zásadní zrada nastává, pokud dojde při startu počítače k detekování TV karet v jiném pořadí, než v jakém byly rozpoznány tehdy, když jsme je do mythbackendu konfigurovali.
Nejdříve jednoduchý důkaz, že k této situaci opravdu jednou za čas dochází, i když si třeba 100× restartujete, jen abyste si ověřili, že u vás ne. Po sto prvé k tomu náhodou stejně dojde, mimochodem právě ve chvíli, kdy potřebujete moc nutně nahrát nějaký důležitý pořad – viz následující výpis z /var/log/syslog
zobrazující 4 zapnutí mythbackendu v pátek odpoledne:
Feb 5 12:39:00 htpc kernel: [ 9.850792] DVB: registering adapter 0 frontend 0 (Afatech AF9013 DVB-T)... Feb 5 12:39:00 htpc kernel: [ 10.196682] DVB: registering adapter 1 frontend 0 (ST STV0299 DVB-S)... Feb 5 12:39:00 htpc kernel: [ 10.645435] DVB: registering adapter 2 frontend 0 (Conexant CX24116/CX24118)... Feb 5 14:43:18 htpc kernel: [ 9.315456] DVB: registering adapter 0 frontend 0 (Afatech AF9013 DVB-T)... Feb 5 14:43:18 htpc kernel: [ 9.722092] DVB: registering adapter 1 frontend 0 (ST STV0299 DVB-S)... Feb 5 14:43:18 htpc kernel: [ 10.195413] DVB: registering adapter 2 frontend 0 (Conexant CX24116/CX24118)... Feb 5 17:48:17 htpc kernel: [ 9.472184] DVB: registering adapter 0 frontend 0 (ST STV0299 DVB-S)... Feb 5 17:48:17 htpc kernel: [ 9.504940] DVB: registering adapter 1 frontend 0 (Afatech AF9013 DVB-T)... Feb 5 17:48:17 htpc kernel: [ 9.941212] DVB: registering adapter 2 frontend 0 (Conexant CX24116/CX24118)... Feb 5 20:05:20 htpc kernel: [ 9.940885] DVB: registering adapter 0 frontend 0 (Afatech AF9013 DVB-T)... Feb 5 20:05:20 htpc kernel: [ 10.264692] DVB: registering adapter 1 frontend 0 (ST STV0299 DVB-S)... Feb 5 20:05:20 htpc kernel: [ 10.732666] DVB: registering adapter 2 frontend 0 (Conexant CX24116/CX24118)...
V 17:48 se prostě DVB-T Volar X (na USB sběrnici) o 3 setiny sekundy opozdil a dostal se tak nečekaně až za DVB-S SkyStar2 (na PCI sběrnici). Tím pádem se pomíchaly karty v mythbackendu, nenahrály se žádné pořady a WAF byl zásadně ohrožen (WAF = Wife Appreciation Factor je často zaklínaným slovem v MythTV komunitě – vyjadřuje stupeň spokojenosti manželky a dalších rodinných příslušníků se stavem multimediálního centra, a tedy nepřímo i s vámi jakožto jeho správcem). Ve 20:05 jsem to „opravil“ pouhým restartem systému.
V podstatě stejná situace nastává u dálkových ovládání, které jsou už převedené na univerzální vstupní architekturu v Linuxu, a tedy se objeví v /dev/input/eventX (X opět roste od nuly podle pořadí detekování). Tady stačí, abychom například připojili či odpojili klávesnici, myš nebo jinou TV kartu, která má taky své dálkové ovládání, a hned se rozsype naše pečlivě vyladěná konfigurace LIRC, ve které máme zapsanou cestu například /dev/input/event5, zatímco ovladač se před chvilkou posunul na event6 či 4.
Jak z toho ven? Řešením je přesvědčit udev, aby nám poskytl nějaký pevný bod, soubor se jménem, které se nezmění při příštím restartu. Možnosti jsou dvě. Za prvé, upravit konfiguraci udev tak, aby nám kromě těch automaticky číslovaných souborů vytvořil i symbolické linky s nějakým normálním pevným jménem – tento symlink bude vždy ukazovat na správnou kartu a proto budeme moci jeho jméno použít pro stabilní konfiguraci mythbackendu. Druhá možnost je přemluvit udev, ať čísla nepřiřazuje podle pořadí detekování, tedy jak jsem předvedl výše v podstatě náhodně, ale ať dává konkrétním zařízením stále stejná čísla.
První možnost – symbolická jména
Nechci tady zabíhat moc podrobně do konfigurace udev, která byla jistě popsána detailně už dříve, takže jen naznačím potřebné kroky pro vytvoření stabilního jména dálkového ovladače pro LIRC konfiguraci:
1) ve /var/log/syslog (nebo ve výstupu příkazu dmesg
) si najdeme, jak se ta TV karta (či jiné vstupní zařízení) jmenuje právě teď – třeba moje TeVii S460, jejíž dálkové ovládání aktuálně používám, dnes nabootovala pod názvem /dev/dvb/adapter2/frontend0.
2) požádáme udev, ať nám vypíše všechny informace, co o tomto zařízení zná (výpis jsem pro potřeby článku zkrátil). A pokud udevinfo
už nemáte (protože máte hodně nový udev díky nové distribuci), použijte místo něj na obou místech následujícího řetězce příkazů udevadm info
:
# udevinfo -a -p $(udevinfo -q path -n /dev/input/event5) looking at device '/devices/pci0000:00/0000:00:06.0/0000:01:07.2/input/input5/event5': KERNEL=="event5" SUBSYSTEM=="input" DRIVER=="" looking at parent device '/devices/pci0000:00/0000:00:06.0/0000:01:07.2/input/input5': KERNELS=="input5" SUBSYSTEMS=="input" DRIVERS=="" ATTRS{name}=="cx88 IR (TeVii S460 DVB-S/S2)" ATTRS{phys}=="pci-0000:01:07.2/ir0" ATTRS{uniq}=="" ATTRS{modalias}=="input:b0001vD460p9022e0001-e0,1,14,k71,72,73,74,86,8B,9E,A4,A7,A8,D0,E3,160,166,167,16C,16D,16E,172,174,182,188,18B,192,193,195,196,ramlsfw"
3) najdeme si některý z atributů, který je dostatečně unikátní a popisuje právě to zařízení, které chceme identifikovat a vytvořit pro něj stabilní symbolické jméno. Protože mám v systému právě jednu TeVii kartu, stačí mi se chytit atributu „name“, abych dálkové ovládání identifikoval jednoznačně. Mít těch karet víc stejných, asi bych se musel chytit ještě třeba čísla PCI slotu (toho „pci-0000:01:07.2“), protože ten se taky při restartech normálně nemění (pokud tedy karty nepřehazuji přímo fyzicky v počítači ze slotu do slotu).
4) vytvoříme nové pravidlo pro udev – v Debianu v adresáři /etc/udev/rules.d/
založíme soubor nazvaný třeba 10-local.rules
(v jiných operačních systémech to bude nejspíš velmi podobné až úplně stejné) a do něj napíšeme
KERNEL=="event?", ATTRS{name}=="cx88 IR (TeVii S460 DVB-S/S2)", SYMLINK+="input/IR-TeVii"
a restartujeme systém, aby udev znovu nadetekoval všechna zařízení (alternativou k restartu by bylo odstranit a znovuzavést ovladač daného zařízení, ale vzhledem k závislostem mezi kernel moduly bude restart celého systému kolikrát nejrychlejší a nejjednodušší).
Zápis toho udev pravidla je jednoduchý a snad nejen pro programátory lehce pochopitelný. Výsledkem je stabilní symbolické jméno /dev/input/IR-TeVii
, ideální pro použití v konfiguraci LIRC:
# ls -l /dev/input/ total 0 drwxr-xr-x 2 root root 60 2010-02-08 07:42 by-id drwxr-xr-x 2 root root 120 2010-02-08 07:42 by-path crw-rw---- 1 root root 13, 64 2010-02-08 07:42 event0 crw-rw---- 1 root root 13, 65 2010-02-08 07:42 event1 crw-rw---- 1 root root 13, 66 2010-02-08 07:42 event2 crw-rw---- 1 root root 13, 67 2010-02-08 07:42 event3 crw-rw-r-- 1 root video 13, 68 2010-02-08 07:42 event4 crw-rw-r-- 1 root video 13, 69 2010-02-08 07:42 event5 crw-rw---- 1 root root 13, 70 2010-02-08 07:42 event6 lrwxrwxrwx 1 root root 6 2010-02-08 07:42 IR-TeVii -> event5 crw-rw---- 1 root root 13, 63 2010-02-08 07:42 mice
Pro ilustraci uvádím níže zbytek obsahu mého 10-local.rules, který vytváří stabilní jména pro dvě dříve používané analogové televizní karty – Pinnacle PCTV Pro a Hauppauge WinPVR 150:
KERNEL=="video?", BUS=="pci", SYSFS{subsystem_device}=="0x0012", SYMLINK+="video-pctv" KERNEL=="vbi?", BUS=="pci", SYSFS{subsystem_device}=="0x0012", SYMLINK+="vbi-pctv" KERNEL=="video?", BUS=="pci", SYSFS{subsystem_device}=="0x8003", SYMLINK+="video-pvr150" KERNEL=="vbi?", BUS=="pci", SYSFS{subsystem_device}=="0x8003", SYMLINK+="vbi-pvr150"
V konfiguraci mythbackendu jsem tedy měl místo anonymního a nejistého /dev/video0
rovnou jasné a stabilní /dev/video-pctv a /dev/video-pvr150
. Ta vbi jména jsou pro čtení teletextu, který se v mythbackendu u analogových karet konfiguruje zvlášť.
Druhá možnost – stabilní čísla zařízení
Druhá možnost je poněkud méně elegantní na konfiguraci, ale pro satelitní digitální karty je vhodnější, jak si ukážeme, až se dostaneme k dekódování signálu. Stejně tak to může být jediná rozumná možnost v případě, že máme kartu s dvojitým tunerem, anebo třeba dvě naprosto identické karty, které udev jednoznačně a spolehlivě nerozliší. V takovém případě můžeme zkusit požádat přímo ovladač/kernelový modul daného zařízení, aby udev přiřadil konkrétní číslo, a to s pomocí parametru adapter_nr. Nejdříve proto musíme zjistit, který kernelový modul vlastně řídí naše TV karty.
Kombinací příkazů dmesg
a lsmod
se dopátráme:
# dmesg | grep DVB [ 8.395388] dvb-usb: found a 'AVerMedia AVerTV DVB-T Volar X' in warm state. [ 8.396018] DVB: registering new adapter (AVerMedia AVerTV DVB-T Volar X) [ 9.289273] DVB: registering adapter 0 frontend 0 (Afatech AF9013 DVB-T)... [ 9.472701] DVB: registering new adapter (FlexCop Digital TV device) [ 9.491565] input: IR-receiver inside an USB DVB receiver as /devices/pci0000:00/0000:00:02.1/usb2/2-2/input/input4 [ 9.491680] dvb-usb: AVerMedia AVerTV DVB-T Volar X successfully initialized and connected. [ 9.772651] b2c2-flexcop: found 'ST STV0299 DVB-S' . [ 9.772693] DVB: registering adapter 1 frontend 5505090 (ST STV0299 DVB-S)... [ 9.775480] cx88[0]: subsystem: d460:9022, board: TeVii S460 DVB-S/S2 [card=70,autodetected], frontend(s): 1 [ 10.164100] input: cx88 IR (TeVii S460 DVB-S/S2) as /devices/pci0000:00/0000:00:06.0/0000:01:07.2/input/input5 [ 10.190782] cx88[0]/2: subsystem: d460:9022, board: TeVii S460 DVB-S/S2 [card=70] [ 10.190828] cx88[0]/2: cx2388x based DVB/ATSC card [ 10.238687] DVB: registering new adapter (cx88[0]) [ 10.238728] DVB: registering adapter 2 frontend 0 (Conexant CX24116/CX24118)...
Naši kandidáti jsou „dvb-usb“ pro AverTV Volar X, „b2c2-flexcop“ pro Technisat SkyStar2 a „cx88“ pro TeVii S460. Ještě najdeme skutečná jména kernel modulů ve výpisu lsmod
(mlčky předpokládám, že používáme modulární, nikoliv monolitický kernel). Pokud máme kandidátů víc, tak příkazem modinfo jmenomodulu
kontrolujeme, který z modulů má pro nás klíčový parametr adapter_nr.
# lsmod | grep dvb_core dvb_core 75592 6 dvbloopback,cx88_dvb,videobuf_dvb,stv0299,b2c2_flexcop,dvb_usb
V závislostech modulu „dvb_core“ najdeme jména kernel modulů, která jsme hledali: „dvb_usb“, „b2c2_flexcop“ a „cx88_dvb“. „dvb_usb“ ještě není ten pravý ořechový, ale další lsmod
to vyjasní:
# lsmod | grep dvb_usb dvb_usb_af9015 20880 0 dvb_usb 14572 1 dvb_usb_af9015
Pro kontrolu:
# modinfo dvb_usb_af9015 b2c2_flexcop cx88_dvb | grep adapter_nr parm: adapter_nr:DVB adapter numbers (array of short) parm: adapter_nr:DVB adapter numbers (array of short) parm: adapter_nr:DVB adapter numbers (array of short)
A teď už zbývá jen vybrat a přiřadit stabilní čísla, nejlépe nějaká vyšší než nula, abychom nenarazili na kolizi, až příště přidáme další DVB zařízení (stačí totiž třeba jen zastrčit USB kameru do multimediálního centra, nebo další USB tuner a DVB číslování se opět celé posune). V adresáři /etc/modprobe.d/
proto vytvoříme soubor nazvaný třeba dvb a do něj napíšeme (příklad pro moje karty):
options b2c2-flexcop adapter_nr=5 options cx88_dvb adapter_nr=6 options dvb_usb_af9015 adapter_nr=7
Tím vlastně přidáme parametr adapter_nr ke třem modulům, což by se mělo po restartu systému projevit:
# reboot # dmesg | grep "registering adapter" [ 9.572115] DVB: registering adapter 7 frontend 0 (Afatech AF9013 DVB-T)... [ 10.064682] DVB: registering adapter 5 frontend 0 (ST STV0299 DVB-S)... [ 10.509536] DVB: registering adapter 6 frontend 0 (Conexant CX24116/CX24118)...
Mimochodem, adapter_nr očekává pole čísel, takže pokud nám jeden kernelový modul řídí vícero karet, zapíšeme plánovaná čísla jednoduše oddělena čárkami, například:
options cx88_dvb adapter_nr=3,4,5
Tak a je to – zbývá opravit existující konfiguraci MythTV, což nejlépe provedeme tak, že v mythtv-setup
zrušíme úplně všechny karty a začneme znovu. Hackeři mohou přímo editovat tabulku capturecard databáze mythconverg a ručně tam jména karet poměnit (za případné následné bolesti hlavy si pak mohou sami).
Pro kontrolu výpis konfigurace mythbackendu přímo z MySQL databáze:
# echo "SELECT DISTINCT videodevice FROM capturecard" | mysql mythconverg videodevice /dev/dvb/adapter5/frontend0 /dev/dvb/adapter6/frontend0 /dev/dvb/adapter7/frontend0
A to je vše – WAF by měl být nyní vysoký a nahrávky 100% spolehlivé. Za pointer na správné řešení stabilních čísel děkuji Milošovi.
Příště
Příště si povíme něco o tom, o čem se veřejně na internetu (především na mythtv.org) moc nemluví – kde a jak získat kvalitní televizní program, a taky jak legálně dekódovat české/slovenské satelitní televizní programy.