symlink | misc | DVB-T

I have an old "TV tuner" PCI card which is capable of receiving DVB-T, in addition to analog. It is based on the Philips TDA10046H tuner chip:

saa7134: saa7133[0]: registered device video0 [v4l2]
saa7134: saa7133[0]: registered device vbi0
saa7134: saa7133[0]: registered device radio0
saa7134_dvb: dvb_init() allocating 1 frontend
dvbdev: DVB: registering new adapter (saa7133[0])
saa7134 0000:04:01.0: DVB: registering adapter 0 frontend 0 (Philips TDA10046H DVB-T)...        
dvbdev: dvb_create_media_entity: media entity 'Philips TDA10046H DVB-T' registered.
dvbdev: dvb_create_media_entity: media entity 'dvb-demux' registered.
tda1004x: setting up plls for 48MHz sampling clock
tda1004x: found firmware revision 23 -- ok
saa7134_alsa: saa7134 ALSA driver for DMA sound loaded
saa7134_alsa: saa7133[0]/alsa: saa7133[0] at 0xf7c04000 irq 16 registered as card -1

(It seems that the card has built-in firmware, so I didn't need to do anything to extract it from Windows.)

The card doesn't do any video decoding on its own, merely outputs the raw MPEG-TS stream to userspace where it can be read via /dev/dvb/adapter0/dvr0 after the adapter has been tuned to the right frequency. (dvb5-zap or the older tzap are used for that purpose.)

DVB-T typically multiplexes several channels as "services" over a single MPEG-TS stream, which means they can be received concurrently without re-tuning the receiver. Software tends to be a bit lazy about it – when using software like VLC or MuMuDVB, only channels on a single pre-configured frequency can be received; it tunes the receiver on startup and there's often no way to change it on the fly.

Fortunately, the majority of Lithuania's DVB-T channels (LNK, TV3, etc.) share a single Telecentras transmitter and only need tuning into a single frequency. Only the national LRT is separate. (Though the downside of this arrangement is that all said channels are in standard-definition 576p – only LRT has enough bandwidth to transmit its own HD channels alongside SD ones.)

Software

Both Windows and Linux have OS-level support for DVB tuners as a device class.

VLC supports accessing DVB receivers on both platforms, but is not very convenient as it requires manually specifying the frequency each time (in Hertz, not MHz, so you'd better count the trailing zeroes). Once you've opened the device you can receive the TV guide and switch between channels, but only on that frequency.

PotPlayer is a more convenient option for Windows, as it can perform a channel scan across a list of frequencies.

Linux

Linux exposes the tuner via /dev/dvb/adapter0/* which can then be controlled using dvb-apps (older) or dvb-tools (newer, part of v4l-utils on Debian), as well as the standalone w_scan.

First you use w_scan or dvb-apps' scan to (of course) scan for channels across a list of frequencies (you have to provide a frequency list yourself, because the ones at /usr/share/dvb/dvb-t are outdated).

Generate the frequency list (8 MHz step) for legacy dvb-apps, then convert it to the v5 format for dvb-tools:

$ printf "T %d000000 8MHz AUTO AUTO AUTO AUTO AUTO AUTO\n" {474..858..8} > channels-old.conf
$ dvb-format-convert -I CHANNEL -O DVBV5 channels-old.conf channels-new.conf

Scan those frequencies to produce a channel list (which lets you reference channels by name) describing the frequency, modulation, Service ID for demultiplexing, etc. Beware that both old and new tools use the same path to channels.conf, yet expect incompatible formats, so.

Old (dvb-apps):
$ scan channels-old.conf > ~/.tzap/channels.conf
New (dvb-tools):
$ dvbv5-scan channels-new.conf > ~/.tzap/channels.conf
Alternative (w-scan):
$ w_scan > channels.conf

Now you can tune to a channel by name (which configures the frontend0 and demux0 devices), and watch it using any player which supports MPEG:

Old (dvb-apps):
$ tzap -r -S "TV3" &
$ mplayer /dev/dvb/adapter0/dvr0
New (dvb-tools):
$ dvbv5-zap -r "TV3" &
$ mplayer /dev/dvb/adapter0/dvr0

Or directly record everything (either one program or the entire multiplex) into a MPEG-TS stream:

Old (dvb-apps):
$ tzap -o recording.ts "TV3"
New (dvb-tools):
$ dvbv5-zap -P -o recording.ts "TV3"

Network streaming

Instead of the manual method one can use MuMuDVB to set up a network streaming server. It can be configured to host unicast HTTP streams, or to transmit IPTV via multicast. (Without IGMP snooping this produces around 20 Mbps of continuous multicast traffic.)

$ cat mumu.conf
freq=530
autoconfiguration=full
multicast=0
multicast_ipv4=0
multicast_ipv6=0
unicast=1
$ sudo mumudvb -d -c mumu.conf

Once the server is running, point VLC or Windows Media Player at http://caster:4242/bysid/4 or /byname/TV3 (the daemon's output will display the name and Service ID of every channel found on the frequency), or http://caster:4242/playlist.m3u to get a playlist.

For old versions of Windows Media Player, aka mplayer2, the URL must look like it contains a valid file name with some known extension, e.g. /bysid/4.mpg (which fortunately MuMuDVB allows). These older versions also don't correctly recognize the aspect ratio, and will display "16:9 anamorphic" streams as the raw 4:3 that they are under the hood. (WMP 9 has neither of these problems.)