Media Center Technical Discussion 1: Tuners and TuningSpaces

The Media Center TV experience driven by a flexible, multi-standard engine that works with any compatible tuner (including a good number of analog tuner cards and all BDA digital tuner cards) to create portable recordings viewable on any Windows XP machine.  To support “trick play” on Live TV (Pause, FFWD, etc.), the video engine is separated into two main segments: capture and playback.  The capture engine, controlled through the Media Center Receiver Service (ehrecvr.exe), is responsible for creating the actual recordings, including controlling tuners, creating a media stream, and optionally encrypting the stream before writing it to disk.  The playback engine, controlled through the Media Center Shell (ehshell.exe), processes media streams created by the capture engine and renders them for the user.  Everything else, as far as TV goes, is built on top of or leverages these two components.

The capture engine uses the Microsoft Unified Tuning Model, with TuningSpaces and TuneRequests, as a layer on top of the physical tuner, allowing Media Center to treat tuners agnostically.  To actually tune to a channel, Media Center first creates (or looks up) a tune request that corresponds to that channel, then submits it to the capture engine, which uses it to tell the tuner what to do.

A TuningSpace corresponds to code written specifically to handle a type of video broadcast, such as ATSC, NTSC, or DVB-T.  Some properties are present in all TuningSpaces, like its ID (e.g. {8A674B4D-1F63-11D3-B64C-00C04F79498E} for NTSC Analog Cable), and some are specific to an implementation.  The implementation-specific properties--like NetworkType or DefaultLocator for digital standards--let the capture engine configure the underlying BDA driver, and provide a way to tweak default values.  A TuningSpace can be considered a "template" for how Media Center will try to talk to the tuner card, depending on how you have it configured--mapping roughly to the old TV setting of "Antenna" or "Cable".

All by itself, a TuningSpace is not enough to actually tune to a broadcast stream.  For that, Media Center creates a TuneRequest (by using the ITuningSpace object).  A TuneRequest can be thought of as "everything you need to know about tuning to a channel"; what it contains varies from TuningSpace to TuningSpace. For an NTSC tune request, you could expect it to contain a channel number and a reference to the TuningSpace; an ATSC tune request would contain a physical channel (the "major" channel) and a minor channel; a DVB-T tune request would contain the broadcast frequency, ONID, TSID, and SID.  All tune requests contain a reference back to the proper TuningSpace.

Media Center stores information about which TuningSpace(s) are configured on the system on a per-tuner basis in the Windows registry under the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Service\Video\Tuners key.  If you open this key, you'll see something like this:

The GUIDs correspond to "tuning categories", which are digital ({71985F48-1CA1-11D3-9CC8-00C04F7971E0}) and analog ({A799A800-A46D-11D0-A18C-00A02401DCD4}), each containing subkeys that correspond to individual tuner devices.  Note that there can be more than one tuner device per physical tuner card or USB device--Media Center treats multi-tuner cards as separate devices.  I will use my Hauppauge WinTV PVR PCI II device's entry as an example:

As you can see above, the tuner's auto-generated GUID is {99F4E181-4B58-4258-8547-2CE73F3C0386}.  This key is created by the ehrecvr service automatically when it detects the tuner: for a PCI card, this happens at service startup; for a USB device, this happens either at service startup or when you plug in the device.  If you delete the key and restart the ehrecvr service--and the card is still installed--a key will be created with a new GUID.  If a USB device is detached and reattached to a different port it will also get a new key.

Examining the properties, there are a couple of interesting values:

  • ConfiguredTuningspace is a REG_MULTI_SZ that contains a list of the TuningSpace IDs for which this card has been configured in Media Center.
  • SupportedTuningspace contains a list of the TuningSpace IDs with which the tuner's driver reports compatibility.  These lists can differ if the tuner supports more than one type of tuning, like some of the newer "hybrid" tuners--a card that supports both NTSC and PAL is an example of such a card. 
  • DevInstance, DevName, and DevPath are obtained from the tuner driver, and give Media Center "pointers" to the physical device.  If you open up Device Manager and look at the advanced properties for the matching device, you will find that the values map 1:1 to entries here.
  • PrefEncoder either points to another hardware ID (in the case of a tuner with hardware MPEG2 encoding) or a software encoder (e.g. ATI AIW cards).  This is populated after we successfully build a capture graph for the device, and points to the MPEG2 encoder that is included in the graph at that time.

It's important to note that ehrecvr will create a key for every tuner device detected, whether or not it is configured in Media Center or not.  Whether it is available for tuning in Media Center is just a matter of whether the registry keys says it is.  For example, you can easily get more than 2 tuners working for scheduling, recording and Live TV viewing by editing the registry entries for the tuners to enable them.  The reason that you cannot do this through the UI is simply because there is not a good graphical way to resolve recording/viewing conflicts amongst more than 2 tuners for a given TuningSpace.  Instead of being able to choose which of the 4 tuners to "steal", you can only choose from 2 of them.  However, with 4 tuners you're much less likely to actuallyneed conflict resolution, so IMHO it's acceptable.

To actually get the n-tuner scenario working properly, every tuner must be in the same TuningSpace, and change channels the same way.  So you cannot mix STB with non-STB, Satellite with Cable, etc. This is due to limitations in the Guide and PVR engine, not in the capture or playback engines.  STB tuners are somewhat of a pain, so I recommend using Method 2 (below) if you are going to go with n-tuners on STBs.  Also, you must have an STB for each and every tuner... not a fun scenario if you have to pay for each one. 

This week's Media Center tweak is getting N tuners working in Media Center.  There are various versions floating around out there on the internet, most of which include extra, unnecessary steps, likely because the authors figured out this stuff without the benefit of internal knowledge of the codebase, so they included everything they did to get it all working.  The version of this tweak posted on The Green Button works just like Method 2 below, but requires a reboot between each configuration run.

If you have NTSC + ATSC, you can use this method for the ATSC tuners, the NTSC tuners, or both!  The only limitations are your hard drive's bandwidth, your system bus bandwidth, CPU time, and the number of tuners you can attach to the machine.  For NTSC that means a practical limit of about 10 tuners, if they are all recording non-DRM content.  For High Definition ATSC and DVB it's a little more intensive, but since there's no encoding going on (digital broadcasts are already encoded!), it actually balances out a little, with a top limit of around 7-8 tuners.  I have personally run 3 ATSC + 6 NTSC on my home system (through dual-tuner USB devices like the Adaptec AVC-3610), and it hummed right along (1 GB DDR Dual-Channel DDR 3200 RAM, Pentium 4 2.8 GHz (HT), 2x 7200 RPM 500GB Hitachi SATA drives in RAID-0 with the system/boot drive on a 40 GB PATA drive).  That's a bit more than I need, so I backed off to only 3 NTSC (2 USB + 1 PCI) and 2 ATSC (both PCI).

Step-by-step, here's how to get n-tuner going.  Both methods assume you've already installed the tuners and have the drivers installed. 

N Tuners in MCE, Method 1 (only registry editing):

  1. Stop the Media Center Receiver Service (net stop ehrecvr)

  2. Open Registry Editor (regedit.exe) and open this key:
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Service\Video\Tuners\ {GUID}
    where {GUID} is either {71985F48-1CA1-11D3-9CC8-00C04F7971E0} for Digital (ATSC or DVB-T) or {A799A800-A46D-11D0-A18C-00A02401DCD4} for Analog (NTSC or PAL).

  3. Under the {GUID} key, there will be one key per tuner device.

  4. Select the first tuner's key.

  5. Select the UserSettings key.

  6. Set these DWORD values as follows (case sensitive, all values in hexadecimal), creating them if they do not exist:
    EnabledForMCE = 0xffffffff
    UseSTB = 0

  7. Create a REG_SZ value named UserDefName and set its value to "Tuner X", where X is the tuner number (1 for the first tuner, 2 for the 2nd, etc.)

  8. If this is the FIRST tuner:
    RecordOrder = 0
    RecordPrefered = 0xffffffff
    WatchOrder = number of tuners - 1, e.g. for 4 tuners set this to 3
    WatchPrefered = 0

    If this is the LAST tuner:
    RecordOrder = number of tuners - 1, e.g. for 4 tuners set this to 3
    RecordPrefered = 0
    WatchOrder = 0
    WatchPrefered = 0xffffffff

    If this is a tuner somewhere in the middle:
    RecordOrder = whatever you put for the last tuner + 1
    RecordPrefered = 0
    WatchOrder = whatever you put for the last tuner - 1
    WatchPrefered = 0

    The idea here is that you increment the RecordOrder by 1 for each tuner, and decrement the WatchOrder by 1.  RecordOrder starts at 0 on the first tuner and goes up to #Tuners - 1; WatchOrder starts at #Tuners - 1 and ends at 0 on the last tuner.  RecordPrefered is true (0xffffffff) on the first tuner, false (0x00000000) everywhere else; WatchPrefered is true on the last tuner, false everywhere else.

  9. Repeat steps 7 - 10 for each tuner, adjusting the values of RecordOrder, RecordPrefered, WatchOrder and WatchPrefered as appropriate.

  10. Close Registry Editor.

  11. Start Media Center. Voila!

Yes, "Prefered" is misspelled.  We caught that after we shipped, and it's a little late to change now...

N Tuners in MCE Method 2 (a little registry stuff, no manual editing though):

  1. Start the Media Center shell (Green Button)
  2. Go to Settings-->TV-->Set Up TV Signal
  3. Choose the 2 tuners from the list of tuners that you will configure this time (first time through, just the first 2)
  4. Close the Media Center shell.
  5. Stop the Media Center Receiver service (net stop ehrecvr or stop the service from Control Panel-->Administrative Tools-->Services)
  6. Open Registry Editor (regedit.exe) and open this key:
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Media Center\Service\Video\Tuners\ {GUID}
    where {GUID} is either {71985F48-1CA1-11D3-9CC8-00C04F7971E0} for Digital (ATSC or DVB-T) or {A799A800-A46D-11D0-A18C-00A02401DCD4} for Analog (NTSC or PAL).
  7. Under the {GUID} key, there will be one key per tuner device.
  8. Find the 2 keys that were just configured by Media Center.  You can tell which ones they are by looking for the "EnabledForMCE" value under the UserSettings key.  If it is set to 0xffffffff, it was configured--otherwise it will be 0x00000000 (0).
  9. Export the 2 keys to .reg files on your hard disk. (right-click on the {GUID} key and choose Export [selected branch only]).  Make a note of where you save those files... you're going to need them!  Name each one differently (e.g. Tuner1.reg, Tuner2.reg).
  10. Repeat steps 1 - 8 for each set of 2 tuners (if you have 3, then just then 3rd, etc.), selecting different tuners each time.
  11. Repeat steps 4 and 5.
  12. Double-click on each of the .reg files you created in step 9 to import them into the registry.
  13. Close Registry Editor.
  14. Start Media Center. Voila!

Next week we'll talk about the PVR engine and recording management.

This posting is provided AS-IS with no warranties.  The views expressed above do not represent those of Microsoft Corporation.