Microsoft DirectX 9.0 |
Because DirectShow is modular, it requires a way to describe the format of the data at each point in the filter graph. For example, consider AVI playback. Data enters the graph as a stream of RIFF chunks. These are parsed into video and audio streams. The video stream consists of video frames, which are probably compressed. After decoding, the video stream is a series of uncompressed bitmaps. The audio stream goes through a similar process.
Media Types: How DirectShow Represents Formats
The media type is a universal and extensible way to describe digital media formats. When two filters connect, they agree on a media type. The media type identifies what kind of data the upstream filter will deliver to the downstream filter, and the physical layout of the data. If two filters cannot agree on a media type, they will not connect.
For some applications, you will never have to worry about media types. In file playback, for example, DirectShow handles all of the details. Other kinds of applications may need to work directly with media types.
Media types are defined using the AM_MEDIA_TYPE structure. This structure contains the following information:
The pbFormat member is typed void*
because the layout of the format block changes depending on the media type. For example, PCM audio uses a WAVEFORMATEX structure. Video uses various structures, including VIDEOINFOHEADER and VIDEOINFOHEADER2. The formattype member of the AM_MEDIA_TYPE structure is a GUID that specifies which structure is contained in the format block. Each format structure is assigned a GUID. The cbFormat member specifies the size of the format block. Always check these values before dereferencing the pbFormat pointer.
If the format block is filled in, then the major type and subtype contain redundant information. The major type and subtype, however, provide a convenient way to identify formats without a complete format block. For example, you can specify a generic 24-bit RGB format (MEDIASUBTYPE_RGB24), without knowing all of the information required by the VIDEOINFOHEADER structure, such as image size and frame rate.
For example, a filter might use the following code to check a media type:
HRESULT CheckMediaType(AM_MEDIA_TYPE *pmt)
{
if (pmt == NULL) return E_POINTER;
// Check the major type. We're looking for video.
if (pmt->majortype != MEDIATYPE_Video)
{
return VFW_E_INVALIDMEDIATYPE;
}
// Check the subtype. We're looking for 24-bit RGB.
if (pmt->subtype != MEDIASUBTYPE_RGB24)
{
return VFW_E_INVALIDMEDIATYPE;
}
// Check the format type and the size of the format block.
if ((pmt->formattype == FORMAT_VideoInfo) &&
(pmt->cbFormat >= sizeof(VIDEOINFOHEADER) &&
(pmt->pbFormat != NULL))
{
// Now it's safe to coerce the format block pointer to the
// correct structure, as defined by the formattype GUID.
VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
// Examine pVIH (not shown). If it looks OK, return S_OK.
return S_OK;
}
return VFW_E_INVALIDMEDIATYPE;
}
The AM_MEDIA_TYPE structure also contains some optional fields. These can be used to provide additional information, but filters are not required to use them: