DirectShow学习
+ -

DirectShow 图形过滤(Filter)管理器介绍

2021-02-24 494 2

Filter Graph Manager也是一个COM组件,它是DirectShow的控制中心,它控制Filter的运行。它有以下几个功能:

  • 协调各个Filter的状态。Filter有运行,暂停,停止三种状态,在Filter Graph中,各个Filter的状态必须协调一到,否则会引起冲突。Filter Graph Manager互责协调各个Filter的状态。
  • 提供一个参考时间,用以同步音频流和视频流。
  • 提供一套用于建立Filter Graph的方法
  • 与应用程序进行交互,它会将Filter Graph内部发生的事件,通过消息的方式通知应用程序。

这里对每一种功能都作了简要的描述。

  • 状态改变(State changes):筛选器中的状态更改必须按特定顺序发生。因此,应用程序不会直接向过滤器发出状态更改命令。相反,它向过滤器图形管理器发出一个命令,后者将命令分发给每个过滤器。查找的工作方式与此类似:应用程序将醒询命令发送给过滤器图形管理器,后者将其分发给过滤器。
  • 参考时钟(Reference clock)。图中的所有过滤器使用相同的时钟,称为参考时钟。基准时钟确保所有流都是同步的。应该呈现视频帧或音频样本的时间称为呈现时间。呈现时间是相对于基准时钟测量的。滤波器图管理器选择一个参考时钟,通常是声卡上的时钟或系统时钟。
  • 图表事件(Graph events)。过滤器图管理器使用事件队列通知应用程序过滤器图中发生的事件。这种机制类似于Windows消息循环。
  • 图形构建方法(Graph-building methods)。过滤器图管理器为应用程序提供了向图中添加过滤器、将过滤器连接到其他过滤器以及断开过滤器连接的方法。

DiretShow常用过滤器(filter)

  • IGraphBuilder:为应用程序提供创建过滤器图表的方法。
  • IMediaControl:提供控制过滤器图表中多媒体数据流的方法,包括运行、暂停和停止。
  • IMediaEventEx:继承自IMediaEvent接口,处理过滤器图表的事件。
  • IVideoWindow:用于设置多媒体播放器窗口的属性,应用程序可以用它来设置窗口的所有者、位置和尺寸等属性。
  • IBasicAudio:用于控制音频流的音量和平衡。
  • IBasicVideo:用于设置视频特性,如视频显示的目的区域和源区域。
  • IMediaSeeking:提供搜索数据流位置和设置播放速率的方法。
  • IMediaPosition:用于寻找数据流的位置。
  • IVideoFrameStep:用于步进播放视频流,可使DirectShow应用程序,包括DVD播放器一次只播放一帧视频。

媒体类型(Media Type)

媒体类型使用结构体AM_MEDIA_TYPE表示:

  媒体类型是描述数字媒体格式的一种通用的可扩展方式。两个过滤器相连时,必须使用一致的媒体类型,否则这两个过滤器就不能相连。媒体类型能识别上一级过滤器传送给下一级过滤器的数据类型,并对数据进行分类。

  实际在很多应用程序中,用户根本不需要担心媒体类型的问题,DirectShow会处理好所有的细节。但有些应用程序需要对媒体类型进行操作。媒体类型一般可以有两种表示:AM_MEDIA_TYPE和CMediaType。前者是一个结构,后者是从这个结构继承过来的类。

typedef struct _AMMediaType {
  GUID     majortype;
  GUID     subtype; 
  BOOL     bFixedSizeSamples;
  BOOL     bTemporalCompression;
  ULONG    lSampleSize;
  GUID     formattype;
  IUnknown *pUnk;
  ULONG    cbFormat;
  BYTE     *pbFormat;
} AM_MEDIA_TYPE;

  每个AM_MEDIA_TYPE由三部分组成:Major type、Subtype和Format type。这三个部分都使用GUID(全局唯一标识符)来唯一标示。

  • Major type主要定性描述一种媒体类型,这种媒体类型可以是视频、音频、未解析的字节流或MIDI数据等等;
  • Subtype进一步细化媒体类型,如果是视频的话可以进一步指定是RGB-24,还是RGB-32,或是UYVY等,如果是音频类型 ,可以是PCM音频,MPEG-1负载等。Subtype提供了比 Major type更多的信息,但它并没有定义有关格式的所有信息。例如,视频子类型没有定义图像大小或帧速率,这些其实是通过 format block来描述。
    -Format block 详细描述格式的数据块。AM_MEDIA_TYPE结构的pbFormat成员指向格式块,用于描述此数据块。

pbFormat成员的类型为void*,因为格式块的布局根据媒体类型而变化。例如,PCM audio使用WAVEFORMATEX 。视频使用各种结构,包括VIDEOINFOHEADER和VIDEOINFOHEADER2。AM_MEDIA_TYPE结构体的formattype成员是一个GUID,用于指定格式块中包含的结构。每个格式结构都分配了一个GUID。cbFormat成员指定格式块的大小。在取消引用pbFormat指针之前,请始终检查这些值。

  如果媒体类型的三个部分都指定了某个具体的GUID值,则称这个媒体类型是完全指定的;如果媒体类型的三个部分中有任何一个值是GUID_NULL,则称这个媒体类型是不完全指定的。GUID_NULL具有通配符的作用。

AM_MEDIA_TYPE也包含一些可选字段。这些可用于提供附加信息,但不要求过滤器使用它们:

  • lSampleSize:如果此字段不为零,则定义每个采样(sample)的大小。如果为零,则表示采样大小可能因采样而异。
  • bFixedSizeSamples:如果此布尔标志为TRUE,则表示lSampleSize中的值有效。否则,应该忽略lSampleSize。
  • bTemporalCompression:如果此布尔标志为FALSE,则表示所有帧都是关键帧。

下面是一段媒体类型检查的示例代码:

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;
}
HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936   

0 篇笔记 写笔记

Directshow获取颜色空间分辨率
void GetColorSpaceResolution(){ HRESULT hr; AM_MEDIA_TYPE *pmt = NULL; VIDEOINFOHEADER *pvi = NULL; VIDEO_STREAM_CONFIG_CAPS scc; IAMSt......
DirectShow时钟时间
DirectShow定义了两个相关的时钟时间:参考时间和流时间。参考时间是参考时钟返回的绝对时间。(见参考时钟。)流时间是相对于图形上次开始运行的时间定义的。图形运行时,流时间等于参考时间减去开始时间。图形暂停时,流时间保持在暂停时的流时间。寻道操作后,流时间重置为零。图形停止时,流时间未定义。当媒......
DirectShow 事件产生
要处理DirectShow事件,应用程序需要一种方法来确定事件何时在队列中等待。过滤器图形管理器提供了两种方法:窗口通知:每当出现新事件时,过滤器图形管理器就会向应用程序窗口发送用户定义的窗口消息。事件信号:如果队列中有DirectShow事件,Filter Graph Manager将向Windo......
DirectShow 图形过滤(Filter)管理器介绍
Filter Graph Manager也是一个COM组件,它是DirectShow的控制中心,它控制Filter的运行。它有以下几个功能:协调各个Filter的状态。Filter有运行,暂停,停止三种状态,在Filter Graph中,各个Filter的状态必须协调一到,否则会引起冲突。Filte......
DirectShow播放UVC设备第二路码流方法
双码流播放Graphi图如上。双码流视频设备有两路捕获输出pin, RenderStream函数只会连接第一路pin,要播放第二路码流需要手动获取第二路pin,然后去连接解码器,再手动连接render,就可以显示了。示例代码// m_pGB 是 IGraphBuilder对象// m_pBF......
DirectShow 体系结构
DirectShow技术是建立在DirectDraw和DirectSound组件基础之上的,它通过DirectDraw对显卡进行控制以显示视频,通过DirectSound对声卡进行控制以播放声音。DirectShow的体系结构如下图所示:DirectShow 位于应用层中。它使用一种叫 Filter......
DirectShow实现视频的实时显示并抓图,可以设置视频参数
DirectShow抓图其实是使用IBasicVideo(IID_IBasicVideo)接口获取数据源,进行存储即可。IGraphBuilder* m_pGraphBuild = NULL;hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_......
DirectShow 过滤器之间数据交互
过滤器通过pin连接,连接的两个PIN在在上游过滤器叫做输出pin,下游过滤器的叫做输入pin。数据从上游过滤器传递给下游过滤器通过这两个上游过滤器的输出pin到下游过滤器的输出pin实现。通常,下游过滤器通过IMemInputPin::Receive来接收来自上游过滤器输出pin发送的数据。上下游......
DirectShow数据流
本节介绍DirectShow的数据的工作方式进行介绍。通过滤器之间数据交互一节可知,数据是存在buffer中的。而每个buffer都由一个名为media sample的COM对象包装,该对象实现了IMediaSample接口。Sample由另一种类型的对象(称为分配器)创建的,它由IMemAlloc......
DirectShow 简介
DirectShow是微软Windows操作系统平台关于多媒体架构的一套API接口。使用DirectShow,应用程序可以执行高质量的视频和音频播放或采集。DirectShow提供高质量的多媒体流捕获和播放。它支持多种格式,包括Advanced Systems Format(ASF)、Motion ......
DirectShow Samples和Allocators
在看本节前,我们首先明确2个概念。通过前面的章节可知:Samples是DirectShow过滤器之间传输的数据的封包。Allocators是用于创建Samples的分配器。本节将详细介绍Allocators和Sample的原理。当一个过滤器通过其输出管脚将多媒体数据传输给另一个过滤器(通过其输入管......
DirectShow 接收事件
过滤器图形管理器公开了三个支持事件通知的接口。IMediaEventSink包含筛选器发布事件的方法。IMediaEvent包含应用程序检索事件的方法。IMediaEventEx继承并扩展IMediaEvent接口。过滤器通过调用Filter Graph Manager上的IMediaEventSi......
DirectShow数据传输协议
DirectShow数据传输协议定义为了进行数据交换,DirectShow过滤器(filter)必须支持相关的数据传输协议,这个传输的协议叫做transports。当2个图形过滤器的pin相连接后,它们必须支持相同的transports,除非它们进行数据交换。通常,传输要求其中一个管脚支持特定接口......
DirectShow实时源
实时源(也称为推送push源)实时接收数据。示例包括视频捕获和网络广播。通常,活动源无法控制数据到达的速率。如果满足以下任一条件,则筛选器被视为实时源:过滤器从IAMFilterMiscFlags::GetMiscFlags方法返回AM_FILTER_MISC_FLAGS_IS_SOURCE标志,并......
DirectShow 过滤器的状态
过滤器有三种可能的状态:停止、暂停和运行。暂停状态的目的是提示图形中的数据,以便run命令立即响应。过滤器图形管理器控制所有状态转换。当应用程序调用IMediaControl::Run、IMediaControl::Pause或IMediaControl::Stop时,图形过滤管理器会在所有过滤器上......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!