• AVStream ddk 翻译 分类: DirectX 2014-09-13 10:43 534人阅读 评论(0) 收藏


    1.       AVStream概览

    AVStream是一款微软提供的多媒体类驱动程序,它既支持单独的视频流媒体,也支持音频视频集成的流媒体。微软把AVStream作为操作系统的一部分,在驱动程序ks.sys中导出。硬件供应商只需要编写运行在Ks.sys下层的小驱动程序(minidriver)。

    以前的音频类驱动程序是微软提供的音频端口驱动程序(audio port class driver)。音频供应商应该编写运行在portcls.sys下层的小驱动程序(minidriver)。

    微软仅为已经存在的小驱动程序(minidrivers)提供流媒体类驱动(stream class driver)支持。

    AVStream通过以下几点向供应商提供意义重大的优点:

    l          小驱动(minidriver)程序员可以编写更少的代码。

    l          为音频和视频小驱动程序(minidrivers)提供统一的内核流媒体类模型。

    l          供应商可以使用COM对象加入新的接口,而不需要对已存在的小驱动程序(minidriver)的二进制文件做任何修改。

    在AVStream驱动模型中,供应商提供小驱动程序(minidriver)与微软提供的类驱动程序交互,如下图所示:

     

    2.       AVStream小驱动程序(minidriver)示例

    DDK包含两个AVStream小驱动程序(minidriver)示例:Avshws和Avssamp。Avshws是一个为仿真硬件如何通过AVStream实现DMA而编写的pin-centric捕获驱动程序。Avssamp是一个filter-centric捕获驱动程序,没有实现DMA。

    这些例子演示了本文档中描述的许多概念,而且可以被驱动开发者修改成自己需要的类型。这些例子相关的说明文件(Readme file)可以在DDK中找到,位于这些示例相同的路径中。DDK中未包含这些说明文件。

    3.       AVStream头文件

    所有内核流媒体和AVStream需要引用的材料,包括结构体,函数都在头文件Ks.h中生命。为了访问微软提供的KS和AVStream类驱动程序支持,小驱动程序必需包含这个头文件。

     

    4.       AVStream对象层次图

    AVStream小驱动程序(minidriver)可以通过对象层次图导出许多不同类型的filter,比如,下图就是一个。

    5.       AVStream描述符

    AVStream 小驱动程序(minidriver)在调用KsInitializeDriver例程时,通过提供一个嵌套的描述符结构来描述自己和自己支持的filter类型。每个关键组件-设备,filter类厂和pin类厂都有一个相关的描述符。

    在设备描述符中,FilterDescriptors成员指向KSFILTER_DESCRIPTOR结构体数组,这个数组描述了这个设备可以创建的filter类型。AVStream的客户可以调用KsCreateFilterFactory例程来动态添加filter类厂。

    KSFILTER_DESCRIPTOR表明该filter支持多少类型的pin, filter注册在哪个分类下面,以及filter的拓扑结构。在每个filter描述符中,小驱动程序(minidriver)提供了一个指向KSPIN_DESCRIPTOR_EX结构体数组的指针。每个这样的pin描述符描述一类这个filter可以实例化的pin。你可以调用KsFilterCreatePinFactory例程创建另外的pin类厂。

    典型的AVStream小驱动程序(minidriver)把描述符作为静态变量布置在源文件中,然后调用KsInitializeDriver例程完成创建任务。

    也存在其他类型的描述符,比如,节点描述符KSNODE_DESCRIPTOR,它描述一个给定节点的拓扑结构。

    6.       AVStream派遣表

    AVStream派遣表,KSDEVICE_DISPATCH, 是一套函数指针,指向派遣例程。小驱动程序(minidriver)可以通过提供回调例程完成驱动指定任务的方式,扩展AVStream提供的功能。

    这些小驱动程序(minidriver)提供的例程接收事件的通知消息,并可以扩展或者修改AVStream提供的默认事件处理。

    KSFILTER_DISPATCH和KSPIN_DISPATCH结构体都提供一个叫做Process的派遣例程。使用这个派遣例程区分filter-centric filter和pin-centric filter。要指定一个filter-centric filter,在filtre派遣表中指定一个指向process派遣回调例程的指针。pin-centric filter在每个pin描述符表中,提供一个process派遣例程。

    你可以注册filter,向它发送创建,删除,数据处理和重启等通知。你可以注册pin,向它发送诸如创建,关闭,数据处理,重启,设置数据格式,以及状态改变等事件的通知。要注册通知对象,在相关的派遣结构中指定一个指向供应商提供的派遣例程的指针。

    7.       初始化AVStream小驱动程序(minidriver)

    AVStream小驱动程序(minidriver)自己不处理设备的初始化,而是在DriverEntry例程中调用KsInitializeDriver例程完成初始化。KsInitializeDriver例程初始化驱动程序对象,除此以外还负责初始化IRP派遣例程,PnP 添加设备和卸载设备事件派遣例程。

    在调用KsInitializeDriver时,小驱动程序(minidriver)传递一个需要初始化的指向驱动程序对象的指针,一个指向注册表路径的指针和一个可选的设备描述符对象。如果小驱动程序(minidriver)不传递设备描述符对象,AVStream在调用AddDevice例程时创建具有指定特征的设备对象。

    设备描述符对象包含一个指向KSDEVICE_DISPATCH结构的指针和一个filter描述符数组。为小驱动程序(minidriver)支持的每一类filter提供一个KSFILTER_DESCRIPTOR。当小驱动程序(minidriver)调用KsInitializeDriver时,AVStream为每一类小驱动程序(minidriver)导出的filter创建一个filter类厂对象。当接收到相应filter创建的IRP后,由该类filter类厂分别实例化该filter。每个filter描述符包含一个指向KSPIN_DECRIPTION_EX对象数组的指针。

    当某个filter的给定pin上建立连接时,AVStream pin类厂创建一个pin对象。注意每个filter必需至少导出一个pin。小驱动程序(minidriver)使用KSPIN_DESCRIPTOR_EX的成员InstanceNecessary来确定创建这种类型pin的数目对于filter的正常运行是否必要。同样的,小驱动程序(minidriver)也可以使用KSPIN_DESCRIPTOR_EX结构体的成员InstancePossible来确定创建这种类型pin的数目是否超过最大数目。

    AVStream支持两种处理类型:filter-centric processing 和 pin-centric processing. 当布置好描述符后,就要决定使用哪种处理类型了。

     

    安装AVStream小驱动程序(minidriver)

    AVStream小驱动程序(minidriver)必须存在一个inf文件(系统使用该文件来安装驱动程序)。AVStream的inf文件基于普通inf文件的格式。牢记以下AVStream驱动程序指南。

    如果你为父设备编写小驱动程序(minidriver),inf文件的AddReg一节应该包含:

    [ParentName.AddReg]
    HKR,"ENUM[DeviceName]",pnpid,,"[string]"

    如果你为子设备编写minidriver,inf文件的AddReg一节应该包含:

    [Manufacturer]
    ...=ChildName
    [ChildName]
    ...=ChildName.Device,AVStream[string]
    注意在流媒体类驱动中,上面的"AVStream"应该替换成"Stream"。

    对于所有的AVStream小驱动程序(minidriver), 指定filter应用串必须和KSFILTER_DESCRIPTOR结构中ReferenceGuid成员匹配。

    8.       Pin-Centric Processing

    当编写AVStream小驱动程序(minidriver)时,你的filter可以使用两种处理范例的一种:pin-centric processing or filter-centric processing。

    pin-centric processing指当新的数据帧到达pin队列时,AVStream调用小驱动程序(minidriver)的pin process派遣例程。

    filter-centric processing指当每个实例化的pin上存在有效的数据帧时,AVStream调用小驱动程序(minidriver)的filter process派遣例程。注意这种定义指定了默认的行为;小驱动程序(minidriver)可以通过设置KSPIN_DESCRIPTOR_EX结构体中的flags成员来修改这种默认行为。

    一般来讲,软件filter使用filter-centric processing,硬件filter使用pin-centric processing。比如,支持变换和呈现数据的硬件可以把数据路由到pin-centric filter。相反的情况很少。

    想要得到pin-centric filter,小驱动程序(minidriver)就要在每个KSPIN_DISPATCH结构中提供一个指向AVStrMiniPinProcess回调例程的指针。不要在KSFILTER_DISPATCH结构中指定AVStrMiniPinProcess回调例程的指针。

    如果小驱动程序(minidriver)不修改KSPIN_DESCRIPTOR_EX中的flags设置,AVStream将在以下三种情况下调用供应商提供的AVStrMiniPinProcess回调例程:

    l          该pin进入最小处理状态,队列中必需已经存在数据帧,而且pin必需从欠最小处理状态至少转化成最小处理状态。

    l          新数据帧到达。Pin至少处于最小处理状态,而且在leading edge和之前没有数据帧。

    l          小驱动程序(minidriver)明确调用KsPinAttemptProcessing例程。

    默认情况下,暂停就时最小处理状态。

    另外,如果pin的与门是关闭的,AVStream不调用pin的处理派遣例程。例如,如果你使用KsGateXxx例程添加另外的off输入到该pin的与门,你的处理派遣例程将不被调用。

    当AVStream调用AVStrMiniPinProcess例程时,它提供一个指向存在有效数据pin的指针。随后小驱动程序(minidriver)通过调用KsPinGetLeadingEdgeStreamPointer例程请求leading edge指针。小驱动程序(minidriver)将使用流媒体指针(stream pointer)API管理流媒体数据。

    当AVStream调用AVStrMiniPinProcess例程时,通过设置KSPIN_DESCRIPTOR_EX结构中的相关标记(flags),使用pin-centric processing的小驱动程序(minidriver)可以备修改。

    如果小驱动程序(minidriver)通过调用KsPinAcquireProcessingMutex例程持有处理互斥量(processing mutex),处理尝试可能会失败。如果小驱动程序(minidriver)使用KsGate*调用直接管理门,问题可能同样会出现。

    9.       Filter-Centric Processing

    10.  AVStream中的事件处理

    AVStream filter和pin通过在结构体KSFILTER_DESCRIPTOR或者KSPIN_DESCRIPTOR_EX的AutomationTable成员中提供一个KSAUTOMATION_TABLE类型的结构体,描述它们支持的属性,事件和方法。

    要支持事件,AVStream小驱动程序(minidriver)就要在自动操作表中提供一个KSEVENT_SET类型的数组。每个KSEVENT_SET结构包含一个KSEVENT_ITEM数组。每个KSEVENT_ITEM结构描述了小驱动程序(minidriver)如何支持指定的事件。

    通过在KSEVENT_ITEM结构中提供AVStrMiniAddEvent和AVStrMiniRemoveEvent处理函数,Minidriver可以自定义事件的行为。

    当AVStream接收到一个事件使能请求后,它便产生一个KSEVENT_ENTRY结构。如果小驱动程序(minidriver)已经提供了一个AVStrAddEvent处理函数,AVStream会在调用AVStrAddEvent的时传递一个指向KSEVENT_ENTRY结构的指针。

    如果没有提供AVStrAddEvent处理函数,AVStream默认情况下会添加一个事件到对象列表。小驱动程序(minidriver)不会接收到KSEVENT_ENTRY的指针。Minidriver可以调用KsFilterGenerateEvent或者KsPinGenerateEvents触发一个事件。

    11.  用户模式中方法和事件代码实例

    这部分代码展示了如何在用户模式的KsProxy插件程序中使用方法和事件。

    在你的minidriver中提供了对给定方法支持后,你可以通过调用IksControl::KsMethod方法达到调用底层方法的目的,下面是例子代码:

     

    PVOID MethodBuffer; // Your method arguments buffer
    ULONG MethodBufferSize; // Your method buffer size

    KSMETHOD Method;
    ULONG BytesReturned;

    Method.Set = KSMETHODSETID_MyMethodSet;
    Method.Id = KSMETHOD_MyMethodId;
    Method.Flags = KSMETHOD_TYPE_SEND;

    HRESULT hr = 
    pIKsControl -> KsMethod (
        &Method,
            sizeof (Method),
        MethodBuffer,
        &MethodBufferSize,
        &BytesReturned);

     

    在内核模式自动操作表中,你可以是用KSMETHOD_ITEM的Flags成员指定该缓冲区是否是可读写的,是否是可映射或者可拷贝的。

    要注册一个minidriver支持的事件,使用一下示例代码:

     

    HANDLE EventHandle; // Your event handle.

    KSEVENT Event;
    KSEVENTDATA EventData;

    Event.Set = KSEVENTSETID_MyEventSet;
    Event.Id = KSEVENT_MyEventId;
    Event.Flags = KSEVENT_TYPE_ENABLE;

    EventData.NotificationType = KSEVENTF_EVENT_HANDLE;
    EventData.EventHandle.Event = EventHandle;
    EventData.EventHandle.Reserved [0] = 0;
    EventData.EventHandle.Reserved [1] = 0;

    ULONG BytesReturned;

    HRESULT hr =
    pIKsControl -> KsEvent (
        &Event,
            sizeof (Event),
        &EventData,
            sizeof (EventData),
        &BytesReturned);

     

    在上面的示例中,通知将持续除非minidriver让该事件失效。要让你的事件失效。调用KsControl::KsEvent。如果你只想在事件第一次发生时被通知,设置Event.Flags为KSEVENT_TYPE_ONESHOT。

    12.  AVStream子设备

    这部分适用于Microsoft Windows Server 2003和安装了DirectX 9.0及以后版本的早期操作系统。对于你的设备,AVStream可以作为一个总线枚举器运行,Enum分支下的键,AVStream都为你创建一个子设备。要这样做,在注册表中设备键下放置一个Enum子键。

    特别是在驱动程序的inf文件的AddReg部分,供应商为每个Enum下的子项REG_SZ类型的pnpid值。AVStream使用这个串值为每个单独的设备构造一个PnP硬件ID。

    在DirectX 9.0以前的发行版本中,AVStream创建一个形如"AVStream<pnpid>"子设备硬件ID。

    例如,供应商在inf文件的AddReg部分指定一下设置:

    [MyTVDevice.AddReg]
    HKR,"ENUMCrossbarDevice",pnpid,,"MyCrossbar"
    HKR,"ENUMTunerDevice",pnpid,,"MyTuner"

    因此,AVStream使用下面的设备ID创建两个子设备。

    AVStreamMyCrossbar,AVStreamMyTuner

    为了解决两个子设备指定相同的pnpid这种可能的冲突。DirectX 9.0及以后的版本改变了每个子设备的ID报告机制。对于每个通过父设备报告的硬件ID,AVStream为每个子设备创建一个形如下面的ID:

    AVStream<pnpid>#<modified parent hardware ID>

    修改过的父硬件ID为父硬件ID中使用 “#”代替所有的反斜线””。

    如果最终的串太长,AVStream以MAX_DEVICE_ID_LEN终止ID串,包含一个NULL。在Windows Server 2003,这个限制在头文件cfgmgr32.h中被设置为200个字符。

    例如父设备报告一下的设备ID:

    PCIVEN_XXXX&DEV_YYYY&SUBSYS_ZZZZZZZZ&REV_VV
    PCIVEN_XXXX&DEV_YYYY&SUBSYS_ZZZZZZZZ

    对于pnpid键值为MyCrossbar的设备,AVStream创建一下的子设备硬件ID:

    AVStreamMyCrossbar#PCI#VEN_XXXX&DEV_YYYY&SUBSYS_ZZZZZZZZ&REV_VV
    AVStreamMyCrossbar#PCI#VEN_XXXX&DEV_YYYY&SUBSYS_ZZZZZZZZ

    对于父设备报告的兼容ID,AVStream使用相同的处理方法。AVStream为子设备创建兼容ID形如下面ID:

    AVStream<pnpid>#<modified parent compatible ID>

    兼容ID名称修改机制个长度限制法则与硬件ID是一样的。

    例如,父设备报告了一下兼容ID:

    PCIVEN_XXXX&DEV_YYYY&REV_VV
    PCIVEN_XXXX&DEV_YYYY
    PCIVEN_XXXX&CC_ZZZZZZ
    PCIVEN_XXXX&CC_ZZZZ
    PCIVEN_XXXX
    PCICC_ZZZZZZ
    PCICC_ZZZZ

    MyCrossbar子设备将通过AVStream报告如下的兼容ID:

    AVStreamMyCrossbar#PCI#VEN_XXXX&DEV_YYYY&REV_VV
    AVStreamMyCrossbar#PCI#VEN_XXXX&DEV_YYYY
    AVStreamMyCrossbar#PCI#VEN_XXXX&CC_ZZZZZZ
    AVStreamMyCrossbar#PCI#VEN_XXXX&CC_ZZZZ
    AVStreamMyCrossbar#PCI#VEN_XXXX
    AVStreamMyCrossbar#PCI#CC_ZZZZZZ
    AVStreamMyCrossbar#PCI#CC_ZZZZ
    AVStreamMyCrossbar

    13.   在AVStream中重启处理

    如果下列任何一种情况为真,AVStream将停止处理。

    l          在pin-centric环境中,当前该pin上没有有效的数据。

    l          在filter-centric环境中,至少存在一个pin,该pin的KSPIN_DECRIPTOR_EX的flags没有设置KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING标记,没有数据等待处理。默认情况下,没有设置这个标记。

    l          不管数据真是否有效,小驱动程序(minidriver)的处理派遣回调例程返回STATUS_PENDING。注意处理派遣例程可以是AVStrMiniFilterProcess也可以是AVStrMiniPinProcess,依赖于小驱动程序(minidriver)实现的pin-centric processing或者filter-centric processing。

    当新数据到达空队列时,AVStream开始处理。因此,如果当相关的队列装满,小驱动程序(minidriver)的处理派遣例程返回为STATUS_PENDING时,小驱动程序(minidriver)将不会被调用重新处理。如果小驱动程序(minidriver)设置STATUS_PENDING,minidriver必需调用KsPinAttemptProcessing或者KsFilterAttemptProcessing重新开始处理。

    如果小驱动程序(minidriver)没有真正的处理数据,不要在处理派遣例程中返回STATUS_PENDING。这会引起AVStream马上再次调用小驱动程序(minidriver),导致在AVStream和小驱动程序(minidriver)之间的无限循环

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    《人月神话》读后感第一篇
    MD5+Salt值
    java第十三周测试记录
    今天的问题上上周考试也遇到了,解决方案在文章中。
    Jsp俩大内置对象学习
    十二周周四学术交流会报告
    web界面直连MySql数据库
    抽象类的知识
    isinstance与type的区别
    三级菜单
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706520.html
Copyright © 2020-2023  润新知