Components

 
Microsoft DirectShow 9.0

Components

In the context of MPEG-2, the term component refers to an elementary stream within a program. For example, a program might contain a video stream, two audio streams, a data stream, and so forth.

Components are represented by the IComponent interface. Each component has a type associated with it, represented by the IComponentType interface. The component type describes the component, and may include the media type of the stream. The IComponent interface is also used to activate or deactivate a given component. For example, if a program has two audio streams (say, English and Spanish), typically only one stream is active at a time.

Each tune request has a list of components. Initially this list might be empty, because the actual components have not been identified yet. After the Network Provider tunes to the program, the Transport Information Filter (TIF) begins to receive PSI tables, and is able to fill in some of the component information.

  • Note   Components and component types are not used for analog network types.

To get the components list from a tune request, call the ITuneRequest::get_Components method, which returns a pointer to the IComponents interface. Then call IComponents::EnumComponents, which returns a pointer to the IEnumComponents interface. Use this interface to iterate through the collection:

CComPtr<IComponents> pComponents;
hr = pTuneRequest->get_Components(&pComponents);
if (SUCCEEDED(hr) && (pComponents != NULL))
{
    CComPtr<IEnumComponents> pEnum;
    hr = pComps->EnumComponents(&pEnum);
    if (SUCCEEDED(hr))
    {
        CComPtr<IComponent> pComponent;
        ULONG cFetched;
        while (S_OK == pEnum->Next(1, &pComponent, &cFetched))
        {
            // pComponent contains a pointer to the next component.
        }
        pComponent.Release();
    }
}

After the tune request is submitted to the Network Provider and data is moving through the filter graph, you can get the updated tune request by calling the Network Provider filter's ITuner::get_TuneRequest method. Use the returned ITuneRequest pointer to examine the updated component information. To change which components are active or inactive, update the component list and resubmit the tune request. IComponent::put_Status to change a component's active/inactive status.

Default Preferred Component Types

A tuning space can have a list of preferred component types. If so, the Network Provider uses the list to configure the output pins on the MPEG-2 Demultiplexer filter. Otherwise, the Network Provider creates a default set of output pins:

Pin Description
Pin 1 PSI Tables. This pin connects to the BDA MPEG-2 Transport Information Filter (TIF)
Pin 2 Video
Pin 3 Audio
Pin 4 Data
Pin 5 PSI Tables. This pin connects to the MPEG-2 Sections and Tables filter

To override the preferred component types for a tuning space, do the following:

  1. Get the tuning space from the SystemTuningSpaces collection, as described in Tuning Spaces.
  2. Create a new ComponentTypes collection object.
  3. Create one or more component type objects of the appropriate type. For MPEG-2 streams, use the MPEG2ComponentType object.
  4. Set the desired properties on each component type. At a minimum, set the category (audio, video, and so forth) by calling the IComponentType::put_Category method.
  5. Add each component to the collection by calling IComponents::Add.
  6. Call ITuningSpace::put_DefaultPreferredComponentTypes with a pointer to the component types collection.
  7. Persist the changes by putting the tuning space back into the SystemTuningSpaces collection. Call the ITuningSpaceContainer::put_Item method with a pointer to the tuning space object.

The following code shows these steps:

CComPtr <ITuningSpace> pTuningSpace;  // Pointer to the tuning space.
// Use the SystemTuningSpaces collection to get the tuning space 
// (not shown).

// Create a new component types collection object.
CComPtr<IComponentTypes> pTypes;
hr = pTypes.CoCreateInstance(CLSID_ComponentTypes);

// Create a new MPEG-2 component type.
CComPtr<IMpeg2ComponentType> pType;
hr = pType.CoCreateInstance(CLSID_MPEG2ComponentType);

// Set the category. 
hr = pType->put_Category(CategoryVideo);

// Add the new type to the collection.
CComVariant var;  // Receives the index into the collection.
hr = pTypes->Add(pType, &var);

// (Repeat for each component type.)

// Set the component type collection as the list of default types 
// for the tuning space.
hr = pTuningSpace->put_DefaultPreferredComponentTypes(pTypes);

One reason to set the default component types is to specify a preferred language for an audio stream. Do this by calling the ILanguageComponentType::put_LangID method on the component type.