TV-Out Matrox G400/450

Erstellt am 22.06.2010

TV-out leicht gemacht?

Mit der Anschaffung eines gigantischen Röhrenbeamers fing alles an. Es musste ein Mediacenter her. Als Geek kann ich natürlich nicht einfach ein WindowsMCE installieren und gut ists. Da muss mindestens eine Woche an Linux geschraubt und probiert werden. Das Mediacenter selber ist schnell installiert. Ich habe mich hier nach ersten Gehversuchen mit MyMediaSystem doch für Freevo entschieden, da es doch etwas ausgereifter erscheint. Der langwierigere Part war jedoch den TV-Ausgang der Grafikkarte zu aktivieren. Da ich durch günstige Umstände an einen Futuro C - Thinclient von Fujitsu-Siemens gelangt bin (2,8 GHz Celeron, 512 MB-Ram - warum auch immer sich soetwas noch Thinclient nennen darf?) mit einer Matrox G450 PCI, lag die Idee nahe diese Karte für den TV-Ausgang zu verwenden. Im Internet ließt sich überall, wie toll doch der TV-Ausgang dieser Karte ist und schließlich hatte ich auch noch in meiner Kramkiste einen entsprechenden VGA- auf S-Video-Adapter für eben jene Matrox-Karte.

Dieser Artikel bezieht sich auf die Einrichtung unter openSUSE 11.1, es sollte sich aber auch auf andere Distributionen übertragen lassen. Meine ersten Versuche bestanden darin wilde Xorg.conf-Auswüchse für den mga-Treiber aus dem Internet zu extrahieren. Hier und da sollte man dann auch noch einen Kernel 2.4 patchen; im Endeffekt funktionierte das alles nicht, denn hier kommts: der mga-Treiber kann kein TV-Out! (zumindest nicht der für die G450).

Die Lösung mit matroxfb

Die Lösung des Problems ist der Framebuffer bzw. der matroxfb-Treiber. Damit wird ein Framebufferdevice angelegt (/dev/fb0) über den dann der X-Server sein Bild auf den Monitor schickt (xorg.conf siehe weiter unten). Das ist aber noch nicht alles. Denn um ein Bild über S-Video oder Composite zu erhalten benötigt man auch noch den matroxfb_crtc2-Treiber. Dieser erstellt ein weiteres Framebufferdevice (/dev/fb1) was verwendet wird, um ein Bild auf einen Fernseher zu schicken.

Was wir bisher wissen:

  • mga-Treiber von Xorg kann kein TV-Out
  • matroxfb-Treiber kann TV-Out in Verbindung mit matroxfb_crtc2
  • X-Server muss seine Ausgabe an den Framebuffer schicken

Damit man den Treiber laden kann, darf der Kernel nicht mit dem üblichen vga=0x317-Parameter gestartet werden, sondern mit video=matrox:vesa:0x117 für eine 1024x768er Auflösung bei 16 bit Farbtiefe. Damit der Treiber auch beim Booten geladen werden kann, muss dieser auch in die Initrd. Das kann bei SuSE in der Datei /etc/sysconfig/kernel bewerkstelligt werden. Hier müssen in die Variable INITRD_MODULES noch folgende Module hinzugefügt werden:

matroxfb_base g450_pll matroxfb_g450 matroxfb_Ti3026 matroxfb_accel matroxfb_DAC1064

Die genauen Abhängigkeiten lassen sich mit modprobe --show-depends matroxfb_base erfahren. Durch ein mkinitrd wird die neue Initrd nun mit diesen Modulen gebaut. Teilweise funktionierte die Übergabe der Auflösung nicht. Hier schafft eine Datei in /etc/modprobe.d abhilfe. Einfach eine neue Datei matrox mit dem Inhalt

options matroxfb_base vesa=0x117

anlegen. Dann wird automatisch beim Laden der richtige Modus gewählt.

Um den matroxfb_crtc2-Treiber zu laden habe ich ein kleines Script in /usr/local/bin angelegt: tvout

#!/bin/sh
#rmmod matrox_w1;	# Wenn der Treiber geladen wird, vorher entladen,
					# sonst wird kein Framebuffer-Device angelegt.
modprobe matroxfb_accel;
modprobe matroxfb_crtc2;

Der rmmod-Befehl steht noch drin, da dieser Treiber zunächst immer geladen wurde, aber die korrekte Installation der matroxfb-Treiber verhinderte

Damit sollten jetzt die Gerätedateien /dev/fb, /dev/fb0 und /dev/fb1 existieren. Mit dem Befehl fbset -fb /dev/fb0 bzw. /dev/fb1 kann man sich nun die derzeit im Framebuffer aktivierten Auflösungen anzeigen lassen. Dies dürfte für fb0 eine 1024x768er und für fb1 eine 640x480er-Auflösung sein. Da wir später ein PAL-Signal zum Fernseher senden möchten, stellen wir nun also mit fbset die richtige Auflösung für fb1 ein:

fbset -fb /dev/fb1 -g 768 576 768 576 16 -t 20330 128 32 32 8 128 5;

Diese Zeile kann einfach ans Ende unseres tvout-Scripts. Wichtig ist, dass hier entweder eine Farbtiefe von 16 oder 32 Bit gewählt wird. Mit 24 funktioniert es nicht. Da der X-Server 32 Bit nicht unterstützt habe ich mich für die 16 Bit entschieden.

Noch befinden sich beide Ausgänge im VGA-Modus. Das wollen wir nun ändern. Dazu benötigen wir das sicher schon oft zitierte matroxset-Programm. Das findet ihr z.B. als RPM im Repository von LenzGr. Die nächsten drei Zeilen dürfen ebenfalls in unser Script und schalten den ersten Head als PC-Ausgang, den zweiten als TV-Ausgang und das Signal auf PAL:

matroxset -f /dev/fb0 -m 5;	# deaktiviert zweiten Ausgang
matroxset -f /dev/fb1 -m 2;	# legt zweiten Ausgang auf fb1
matroxset -f /dev/fb1 -o 1 1;	# konfiguriert fb1 für PAL

Jetzt solltet ihr schon durch Eingabe von mplayer -vo fbdev:/dev/fb1 VIDEO.AVI ein Bild auf eurem Fernseher sehen können. Dies wird aber noch ziemlich bis viel zu dunkel sein, also noch ein wenig mehr matroxset-Magic:

matroxset -f /dev/fb0 -c 0x980901 800;

Der erste Wert gibt das Register an, der zweite den Wert im Register, der zwischen 0 und 1023 liegen darf. Welche Register es noch gibt, wie sie heißen und was sie bewirken findet ihr am einfachsten über matroxset -f /dev/fb0 -e heraus. Hier kann man auch ein Testbild erzeugen.

Jetzt kommt das X

Damit ist der Framebuffer soweit eingerichtet, dass man ein Bild auf den Fernseher bekommt. Damit man jetzt auch ein X-System erhält muss noch eine xorg.conf erstellt werden, die die Ausgabe des X-Servers an das Framebufferdevice leitet. Dazu kopiert ihr euch am einfachsten meine Config; viel zu sagen gibt es dazu eh nicht, da sie sehr einfach gehalten ist.

Section "Device"
    Identifier  "MATROX"
    VendorName  "Matrox"
    BoardName   "G450"
    BusID       "PCI:1:0:0"
    Driver      "fbdev"
    Option      "HWcursor" "no"
    Option      "fbdev" "/dev/fb1"
EndSection

Section "Monitor"
    Identifier   "console"
    VendorName   "Unknown"
    ModelName    "Unknown"
    HorizSync    31.5 - 31.5
    VertRefresh  50.0 - 70.0
EndSection

Section "InputDevice"
  Driver       "kbd"
  Identifier   "Keyboard0"
  Option       "Protocol" "Standard"
  Option       "XkbLayout" "de"
  Option       "XkbModel" "microsoftpro"
  Option       "XkbRules" "xfree86"
  Option       "XkbVariant" "nodeadkeys"
EndSection


Section "InputDevice"
  Driver       "mouse"
  Identifier   "Mouse0"
  Option       "AutoSoft" "on"
  Option       "Device" "/dev/input/mice"
  Option       "Emulate3Buttons" "on"
  Option       "Name" ""
  Option       "Protocol" "Auto"
  Option       "Vendor" "Sysp"
EndSection

Section "Screen"
        Identifier "Display"
        Device     "MATROX"
        Monitor    "console"
        DefaultDepth 16
        SubSection "Display"
                Depth     16
                Modes    "768x576"
        EndSubSection
EndSection

Section "ServerLayout"
        Identifier      "tvout"
        Screen          "Display" 0 0
        InputDevice     "Mouse0" "CorePointer"
        InputDevice     "Keyboard0" "CoreKeyboard"
EndSection

So, startklar? Dann kommt jetzt der letzte Teil...

Der Test

Jetzt kommt der spannende Moment, folgende Schritte sind auszuführen:

  • Monitor an den DVI-Ausgang der Karte hängen, TV-Adapter an die VGA-Buchse
  • bootet die Kiste ohne vga=-Parameter ins Runlevel 3 (beim Bootloader 3 eintippen)
  • meldet euch an und führt das tvout-Script aus
  • der Monitor sollte etwas flackern und die Schrift dezent anders aussehen
  • geht mit init 5 ins Runlevel 5, sodass der X-Server startet (und Drückt die Daumen)
  • wenn alles gut gelaufen ist, erscheint das Bild vom X-Server auf dem Fernseher

Als abschließende Arbeit sollte jetzt das tvout-Script noch in eine Datei, wie die /etc/init.d/boot.local geschrieben werden, damit sie jeweils vor dem Start von X ausgeführt wird. Mit diesen Schritten sollte es endlich gelingen ein ordentliches Signal auszugeben. Leider habe ich es noch nicht geschafft die Videobeschleunigung über z.B. VIDIX oder mga_vid zu bekommen. Wie ich es verstanden habe kann mga_vid das auch garnicht, wenn ihr mehr wisst, lasst es mich wissen ;-)

Seitenanfang