Microsoft DirectX 8.0

Writing Digital TV Applications

With the Microsoft® DirectX® 8.0 SDK and a digital TV tuner card that is compatible with Microsoft® Broadcast Driver Architecture (BDA), you can create an application for viewing digital TV broadcasts on the personal computer. Microsoft's architecture for digital television support on the PC can be broken up into the following components:

DirectX 8.0 includes all the filters and associated components necessary to create a basic digital TV filter graph, connect to ATSC (antenna or cable) or DVB-S transmissions, tune the graph and select substreams, capture raw PSI data (such as Electronic Program Guide information) and render the video on the screen.

DirectX 8.0 does NOT include the MSTV Guide Store, which persists EPG data from the PSI stream, or the component for rendering ATVEF enhancements such as Web pages and images for interactive TV. Digital TV applications based on DirectX 8.0 must therefore provide custom implementations for these tasks. DirectX 8.0 also does not provide the Video Control, which means that applications must implement their own code for building the filter graph.

This article contains the following sections:

Digital TV Filter Graph

The following illustration shows a basic BDA digital TV filter graph configured for reception of terrestrial ATSC broadcasts. The actual filter and pin names for the tuner, capture and MPEG-2 decoder filters will vary depending on the vendor.

Generic BDA Digital TV Filter Graph

Network Provider: A BDA Network Provider filter is always the first filter in the graph. This particular graph has the ATSC Network Provider. Microsoft also provides a DVB Network Provider for tuning to DVB networks. Third parties may also provide their own Network Provider that is customized for their own broadcasts. The Network Provider configures the downstream filters for a particular tuning space, which includes information on content multiplexing, modulation, and transmission standards. This filter implements the ITuner interface, which applications use to tune the device to the specified channel or frequency.

Digital TV Tuner: This kernel-mode KsProxy-based filter represents the tuner on the hardware device. It may or may not have any application-callable interfaces, depending on the implementation of the third-party driver. In the BDASample application, the tuner filter is assumed not to support ITuner, and so tuning is performed through the Network Provider, which communicates internally with the Tuner filter.

Digital TV Capture Filter: This kernel-mode KsProxy-based filter represents the demodulator/digitizer on the hardware device. Its single output pin delivers the MPEG-2 transport stream to the MPEG-2 Demultiplexer.

MPEG-2 Demultiplexer: In a digital TV graph, the MPEG-2 demultiplexer accepts the MPEG-2 transport stream from the capture filter and demultiplexes the stream. It typically has four output pins. Its first output pin delivers raw program service information (PSI) packets to the Transport Information Filter. The second pin delivers the video stream to the MPEG-2 decoder. The third pin delivers the audio to the audio decoder, and the fourth pin delivers data such as interactive TV enhancements.

Transport Information Filter: So that a receiver can properly acquire all the elementary streams related to a specific program and so that a receiver can tell what programs are contained in the stream, the transport stream will also contain many sets of tables that act as a catalog of information contained in the transport stream. Under direction of the Network Provider, the MPEG-2 Demultiplexer delivers these tables to the Transport Information Filter, which then parses these tables and provides the information to the Network Provider so that it can control the other receiver filters and nodes in the graph.

HDTV-capable MPEG-2 Decoder: A Digital TV filter graph requires a third-party decoder that is capable of decoding High Definition Television (HDTV) video streams. Some decoder implementations may operate on both audio and video streams in the same filter, while others may have separate filters for audio and video.

Overlay Mixer: This Microsoft® DirectShow® filter performs the actual rendering of the video onto the system's video memory.

Video Renderer: In all graphs that use the Overlay Mixer to render the video, the Video Renderer acts merely as a window manager that informs the Overlay Mixer where on the screen to place the video rectangle.

BDA MPE Filter: This filter extracts IP packets from the Multi-Protocol Encapsulation (MPE) stream and delivers them to IP Sink.

BDA IP Sink: This filter accepts IP packets and delivers them to the host system via Winsock, where interested applications can listen for and receive IP data streams such as interactive TV enhancements.

Building the Filter Graph

For DirectX 8.0, applications must build digital TV graphs by manually adding and connecting each filter. The Capture Graph Builder cannot be used. A sample application, BDASample, is included in the SDK. It demonstrates how to build a basic digital TV filter graph according to the steps outlined later in this section.

The following sections are ordered in roughly the typical sequence of operations that take place during run time. Notice that the building of the filter graph occurs after the tune request is submitted to the Network Provider with the ITuner::put_TuneRequest method. This is because the tune request contains information about the network type and other details that will determine which filters get pulled into the graph. The graph cannot be built until the Network Provider has this information. See The Microsoft® Tuning Model for more information on Tuning Spaces, Tune Requests, and related objects.

Obtain a Tuning Space

For DirectX 8.0, Broadcast Driver Architecture provides default Tuning Spaces for local analog cable and antenna, local ATSC antenna and cable, and DVB-S. A digital cable tuning space is also included, but it is for testing purposes only. To implement digital cable support in your application, overwrite the digital cable tuning space with the values you require, and also supply a default locator if necessary. To support international tuning or digital satellite broadcasts, you will need to create your own tuning space. For DVB tuning spaces, the application will have to provide a user interface that will enable the user to specify which digital television service they have subscribed to.

To obtain a tuning space, the application creates an instance of the SystemTuningSpaces object and uses the ITuningSpaceContainer::get_EnumTuningSpaces method to obtain a list of tuning spaces from which it can select one. This procedure is demonstrated in the BDASample application in the LoadTuningSpace method.

Although the Microsoft Tuning Model is designed to support analog tuning spaces, DirectX 8.0 does not include full support for analog TV tuning in a BDA filter graph. This support will be added in future releases of DirectX and in Microsoft® Windows®. In the meantime, analog TV graphs are supported with the same type of filter graph that DirectShow has traditionally used for analog TV capture. In DirectX 8.0 only digital network types are supported on a BDA filter graph. This means, for example, that if you wish to write an application that supports both digital and analog tuning, your application will need to create two separate filter graphs, and use the analog graph when the user selects an analog TV channel, and the BDA digital graph when the user selects a digital channel or frequency. In future releases of Microsoft Windows, analog and digital television and radio tuning spaces will all be provided, along with an Automation-compliant Video Control that will completely handle the graph-building process.

Create a Tune Request and Submit it to the Network Provider

Applications do not create Tune Requests directly. Instead, an application calls the ITuningSpace::CreateTuneRequest method, which returns an empty, uninitialized Tune Request. The application then calls the standard COM method QueryInterface on the object for a specific interface derived from ITuneRequest, such as IATSCChannelTuneRequest. The application can then use the returned interface to configure the Tune Request, persist it, and submit it to the Network Provider. But before it can submit the Tune Request, the application must first create an instance of the Filter Graph Manager, and then create an instance of the Network Provider filter and add it to the graph. It is important to realize that actually there is no such thing as a generic "Network Provider" filter; instead there is an "ATSC Network Provider," and a "DVB Network Provider." The specific object that is created is based on the network CLSID that is obtained from the Tuning Space object.

After the Network Provider has been added to the graph, use the QueryInterface method to obtain its ITuner interface. Then use the ITuner::put_TuneRequest method to pass the Tune Request to the Network Provider. This procedure is demonstrated in BDASample in graph.cpp in the LoadNetworkProvider function.

Add and Connect the Remaining Filters

Once the Network Provider has been configured with a Tune Request, the remaining filters can be added to the graph one at a time by adding and connecting each filter. See the BuildGraph, LoadAVSegment and LoadIPSegment functions in graph.cpp in the BDASample application.

Define Default Preferred Component Types

Note  This procedure is not implemented in BDASample.

A "component" refers to a program substream. The default preferred component types are those types of substreams that a user wishes to activate by default. For example, a user may specify that a Spanish audio stream should be played whenever one is available. The application creates a set of preferred components by instantiating an empty Components collection object and filling it. The application can then persist and/or submit the Components object to the Tuner, which will check it whenever there are changes in the available substreams.

Select a Substream

Note  This procedure is not implemented in BDASample.

To specify which substreams to activate or inactivate, an application must first submit a Tune Request to the Tuner. Once the Tuner tunes to the specified channel or frequency, it will fill in the Components collection in the Tune Request with information about each active and inactive substream. The application can then examine each component in this collection, and use the IComponent::put_Status method to activate or inactivate a particular substream.

Digital Tuning

After the initial Tune Request has been submitted, subsequent tuning is performed by submitting a new Tune Request to the Network Provider, as demonstrated in BDASample in the ChannelChange method in graph.cpp.