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.
因为 DirectShow 是模块化的,它需要一种方法来描述 filter graph 中每一点的数据格式。例如,关注 AVI 回放,数据以 RIFF 格式的流进入 graph 。被解析为视频流和音频流。视频流由视频帧组成,视频帧有可能被压缩。解码以后,视频流是一系列没有压缩的位图。音频通常被简单处理。
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.
媒体类型是一个广泛的可以扩展的用来描述数字媒体格式的方法。当两个 filter 连接时,他们商定一种媒体类型。媒体类型标识从上有 filter 传递到下游 filter 的数据的种类,以及数据的物理布局。如果两个 filter 没有商定媒体类型,那么他们不会连接。
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.
在一些应用程序中,你不需要担忧媒体类型,例如文件回放, DirectShow 处理所有细节。其他类型的应用程序需要商定媒体类型。
Media types are defined using the AM_MEDIA_TYPE structure. This structure contains the following information:
Major type: The major type is a GUID that defines the overall category of the data. Major types include video, audio, unparsed byte stream, MIDI data, and so forth.
Subtype: The subtype is another GUID, which further defines the format. For example, within the video major type, there are subtypes for RGB-24, RGB-32, UYVY, and so forth. Within audio, there is PCM audio, MPEG-1 payload, and others. The subtype provides more information than the major type, but it does not define everything about the format. For example, video subtypes do not define the image size or the frame rate. These are defined by the format block, described below.
Format block: The format block is a block of data that describes the format in detail. The format block is allocated separately from the AM_MEDIA_TYPE structure. The pbFormat member of the AM_MEDIA_TYPE structure points to the format block.
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.
媒体类型用 AM_MEDIA_TYPE 结构体定义。这个结构体包含下列信息:
Major type :主类型是一个定义数据整体种类的 GUID 。主类型包括视频、音频、未知二进制数据流和 MIDI 数据等等。
Subtype :子类型是另外一个 GUID ,用来进一步定义格式。例如,视频主类型中,包括的子类型有 RGB-24,RGB-32,UYVY 等等。在音频中,包含 PCM , MPEG-1 等等。子类型比主类型提供更多的信息,但是没有定义格式的每一种事物。例如,视频子类型没有定义图像大小或帧率。这些定义在格式块中。
Format block :格式块详细描述格式。格式块从 AM_MEDIA_TYPE 结构中分离出来, AM_MEDIA_TYPE 的 pbFormat 成员指向格式块。
pbFormat 是 void 类型的指针,因为不同的媒体类型格式块的结构会改变。例如 PCM 音频使用 WAVEFORMATEX 结构,视频使用多种结构体,包括 VIDEOINFOHEADER 和 VIDEOINFOHEADER2 。 AM_MEDIA_TYPE 结构的 formattype 成员是一个 GUID ,描述格式块是什么结构体。每一种格式的结构体都会指定一个 GUID 。 cbFormat 描述格式块的大小,使用 pbFormat 指针之前要检测这个值。
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.
如果格式块被填充,那么主类型和子类型包含多余的信息。在没有完整的格式块的情况下,主类型和子类型为定义格式提供一个快捷的方法。例如,可以指定一般的 24-bit RGB 格式,不需要知道 VIDEOINFOHEADER 结构所有的信息,例如图像大小和帧率。
For example, a filter might use the following code to check a media type:
例如,一个 filter 可以使用下面的代码来检测媒体类型:
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:
lSampleSize. If this field is non-zero, it defines the size of each sample. If it is zero, it indicates that the sample size may change from sample to sample.
bFixedSizeSamples. If this Boolean flag is TRUE, it means the value in lSampleSize is valid. Otherwise, you should ignore lSampleSize.
bTemporalCompression. If this Boolean flag is FALSE, it means that all frames are key frames.
AM_MEDIA_TYPE 结构还包含一些可选项,这些可选项用来提供附加信息。 filter 不一定需要它们:
lSampleSize. 如果这个域不为 0 ,它定义采样的大小。如果为 0 ,表示采样的大小会改变。
bFixedSizeSamples. 如果为 TRUE ,表示 lSampleSize 有效,否则忽略 lSampleSize 。
bTemporalCompression. 如果为 FALSE ,标识所有的帧都是关键帧。