Over the last weekend I've dived into some of the details of the MPEG-2 transport streams transmitted for Australian Digital TV with the goal of creating a C# library for scanning digital TV channels. This was largely prompted by a library released at forums.dvbowners.com which looked promising but which I wasn't 100% happy with due to licensing issues and its reliance on an extra DirectShow filter for parsing the MPEG tables. So instead I launched into my own library which performed the parsing itself. Surprisingly this wasn't particular difficult once you understand how the MPEG stream lays out the data. Unfortunately that info wasn't easily available anywhere... hence here's a summary of my findings with pointers to the full details. NOTE: I've only spent a couple of days gathering this info so don't expect it to be 100% correct - please leave corrections in the comments section.
I should be making the code available soon for others to play with so keep an eye on this site if you want to play.
First up, the MPEG stream contains a number of information tables for each frequency. When scanning for channels you simply tune into a certain frequency and gather information from these tables. Tables are identified using two identifiers - their PID (Packet ID) and TID (Table ID). There are quite a few tables involved, but the ones we're interested in for scanning channel info are these:
- Program Association Table (PAT)
- Program Map Table (PMT)
- Service Description Table (SDT)
The PAT is our first port of call. The PAT lists the services available for a certain frequency and is always available on PID 0x00. The PAT tells us two things about each service - its program number and a PID for finding its PMT. The PMT contains a list of all of the streams associated with a service.
The PMT gives us sufficient information for tuning into each channel, but it'd be nice to have the name of the channel. This is available from the SDT which is always available on PID 0x11. The SDT lists extra info for each service including the name of the service.
Many of these tables have a list of descriptors associated with their entries. There are quite a few different types of descriptors defined. For scanning we're particularly interested in the "Service Descriptor" available on the SDT which is where the service's name is found.
Where's the Details
Of course, this doesn't provide anywhere near enough information for actually implementing a scanner, but I can point you in the right direction for getting the details. The most important documents are:
These will give you the layouts of all the tables and descriptors, but hopefully this article will speed up your search a little.
Implementing with DirectShow
DirectShow exposes these tables through the "MPEG-2 Sections and Tables" filter, using the IMpeg2Data interface. This interface takes a PID and a TID and returns the data for them. It should be relatively simple to find another tutorial on setting up a graph which contains this filter so I won't cover that.
Once you have the IMpeg2Data interface the following steps will perform a scan on the frequency that has been tuned into.
- Obtain the PAT by requesting PID 0x00 and TID 0x00
- Parse the PAT to discover the list of services available on this frequency. Store their program numbers and the PID for their PMT.
- Request the PMT for each service using the PID given in the PAT and a TID of 0x02
- Parse the PMT to gather the stream info including PIDs for each video & audio stream (and other streams such as TeleText).
- Request the SDT through PID 0x11 and TID 0x42
- Parse the SDT and search for Service Descriptors which contain the service names
Additionally you can request the Network Information Table (NIT) from PID 0x10, TID 0x40 to get the name of the provider of these services. The documentation indicates there should be a "Terrestrial Delivery System Descriptor" which could provide the actual centre frequency for the network. This could be slightly different to the frequency you originally tuned to, however so far I haven't been able to identify any of these in the actual broadcasts.
EPG (Electronic Program Guide) data is also available from the Event Information Table (EIT) available at PID 0x12, TID 0x4E. I've done some basic tests with this and it's working, but I haven't finished cleaning it up.
Additionally, this work is only mildly attached to DVB-T - it should be pretty much identical for other DVB systems and somewhat close for ATSC based streams.