Streaming TV

... some quick notes on getting streaming digital TV working under Linux.

Kernel and driver

According to Hal, you need at least 2.6.15. On boot, a whole load of modules are loaded:

$ lsmod | grep ^cx
cx88_blackbird         21692  0
cx88_dvb               10660  0
cx8802                 12740  2 cx88_blackbird,cx88_dvb
cx8800                 34668  1 cx88_blackbird
cx88xx                 64384  4 cx88_blackbird,cx88_dvb,cx8802,cx8800

Sometimes, when the machine boots it doesn't seem to detect the card correctly.

cx88[0]: Your board isn't known (yet) to the driver.  You can
cx88[0]: try to pick one of the existing card configs via
cx88[0]: card=<n> insmod option.

... however, after a reboot it was happy again.

Install stuff

We use the Debian packages dvb-utils, mplayer, and vlc.

Scanning for channels

You need a channels.conf file, which tells various apps what frequencies and tuning parameters to use for all the different logical channels. This is generated thusly:

$ scan /usr/share/doc/dvb-utils/examples/scan/dvb-t/au-sydney_north_shore | tee > channels.conf

... however for some reason at KEG we can't get SBS on its normal frequency, only on the Wollongong one. So we have to scan that manually:

$ cat wollongong.scan
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T 711625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE
$ scan wollongong.scan | tee >> channels.conf

Now put channels.conf in the right place for different apps:

$ mkdir -p ~/.tzap ~/.mplayer
$ mv channels.conf ~/.tzap
$ ln -s ~/.tzap/channels.conf ~/.mplayer/channels.conf.ter

Here is the final channels.conf file, also including the (mostly unused) D44 channels.

Testing reception

$ mplayer "dvb://SBS HD"

You can edit the channel names in the channels.conf file to make them easier to use (it's the first field on each line).

Streaming

With dvbstream

The dvbstream package contains a simple app that can dump a stream to the network.

To do unicast streaming to a specific host, we used netcat. The dvbstream program has its own options for generating multicast streams, but we didn't try this.

On the host you want to view the stream do something like:

nc -u -l -p <portnum> | mplayer -cache 8000 -vo xv -

And then on the TV box, we first used tzap to tune the channel in, and then ran dvbstream:

$ tzap "SBS HD"
^C to interrupt it once it acquires a signal (FE_HAS_LOCK)
$ dvbstream -v 102 -a 103 -o | nc -u <target> <portnum>

102 and 103 are the video and audio program IDs respectively. You can find them in the relevant line of channels.conf. dvbstream also has options to specify the frequency and tuning parameters, so it may not be necessary to use tzap, however it doesn't use channels.conf like tzap does, so you may want this script (by Bodo Bauer) to parse the channels file and invoke dvbstream for you.

With VLC

vlc is an all-singing all-dancing media streamer, but in the end we don't use it to do much more than dvbstream does (the only real advantage it offers for multicast is generation of the SAP announcements). See the VLC streaming HOWTO for more detailed docs.

Here is a script to invoke vlc with all the right arguments, you will probably want to edit it to suit your setup: vlcstream.sh

Notes:

To view this stream on a client, you could do:

$ vlc udp:@239.255.42.42

... or alternatively, enable the "SAP Announcements" discovery service (Settings->Preferences->Playlist->Services Discovery), and select "KEG TV" in the playlist when it pops up automatically.

Mumudvb

I haven't tried it, but its author claims that:

... it might be worth a try.

Common problems

Stream doesn't arrive

Check that the kernel supports multicast (CONFIG_IP_MULTICAST). Apparently the default Gentoo kernels have it disabled.

Check for any firewall rules that may be blocking the UDP multicast traffic. With iptables:

iptables -A INPUT -p udp --dst 224.0.0.0/4 --dport 1025: -j ACCEPT

Stream starts playing but stops/pauses after a few minutes

This one was tricky. It turned out that the firewall rules were allowing the UDP data, but blocking the IGMP packets. After a while the switch timed out and stopped sending the stream out that port. The solution was:

iptables -A INPUT -p igmp -j ACCEPT

Multicast across networks

To get streaming working across to other networks:

  1. Enable IGMP on the switch (not really necessary, but it did fix a problem with 10MBit devices getting saturated with unwanted traffic).
  2. Add a route on the gateway box for multicast (put this in startup scripts):
    • route add -net 224.0.0.0 netmask 240.0.0.0 dev eth1
  3. Make sure any firewall rules allow multicast out, and don't attempt to NAT it.
  4. Install and run pimd on the gateway box.

  5. Increase the TTL in the vlc arguments from 1 to 2 (or higher if needed).