DirectX Media Objects

2024-06-12 18:32
文章标签 media directx objects

本文主要是介绍DirectX Media Objects,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



DirectX Media Objects

Microsoft® DirectX® Media Objects (DMOs)是基于COM的数据流组件。在某些部分上,DMOS是类似于Microsoft DirectShow filters。比如对于DirectShow filters, DMOs也是输入数据到创建输出数据。而且,DMOs的APIs比相应的DirectShow的APIs要简单的多。因此,DMOs是比较容易被创建,测试和使用。DMOs可以被用于很多方面:

    基于DirectShow的应用程序通过一个DirectShow filter叫作 DMO Wrapper filter来使用DMOs。而filters与DMOs的区别是,DMOs对于应用程序是透明的。应用程序不用直接访问DMO APIs.

    基于Microsoft DirectSound的应用程序可以使用audio effect DMOs。另外,应用程序通过高级的DirectSound APIs从低级的DMO APIs隔离出来。

    应用程序能够直接使用DMOs.

 

 

关于DMOs

这部分包括如下主题:

       DMOs的优势

       DMO的体系机构

 

DMOs的优势

DMOs提供了如下优势:

 

1、它们通常要比DirectShow filters要小而且简单,因为它们支持较少的功能。

2、它们要比DirectShow filters灵活,因为它们不需要一个filter Graph。当你需要DirectShow提供的一些服务时你可以让DMOs跟随DirectShow,这些服务例如,同步,智能连接,自动处理数据流程和线程管理。那些不需要这些服务的用户能够直接访问DMOs

3DMOs始终是同步数据处理,这样就消除了你写一个filter需要考虑的多线程问题(译者注:filter有独立的数据传送线程,需要考虑多线程编程问题)

4、与传统的ACMVCM codecs不同的是,DMOs是基于组件模型(COM)的,因此,它们通过QueryInterface(接口)的方式进行扩充。

5DMOs支持一个比ACM或者VCM codecs更大众化的流模型a more generalized streaming model)。如同DirectShow filtersDMOs能支持多输入和多输出。

由于这些原因,DMOs现在被推荐为写编码器,解码器和音频效果的解决方案。许多其它的方案可能也很不错,这主要取决于应用程序的需要。

 

DMOsDirectShow Filters有什么不同?

DirectShow filters运行离不开DirectShow filter graph。在DirectShow内,Filter Graph Manager用于应用程序和filters之间的调配。DirectShow filters要做很多数据流需求的工作,包括:

包括分配缓存。

协商媒体类型与连接其它的filters

将数据通过filter graph

发送事件给Filter Graph Manager

多线程的同步。

相对比的是,一个DMO不需要做上面的这些事情。代替的是,这些任务被要求给使用DMOClient去完成。Client负责分配缓存,填充它们数据和递送它们至DMODMO处理这些数据,并且Client从输出缓存中重新得到数据。

 

DMO体系架构

这部分描述DMO的整个体系架构

Streams(流)

 

一个DMO是一个有m个输入n个输出的对象。这些输入与输出被叫做流。每个DMO有至少一个流。流不是对象;它们是通过索引数简单地从DMO上被引用的。这个流的索引数在设计时期就被固定了。

 

Media Types(媒体类型)

 

所有数据都被指明使用一种媒体类型,它定义了如何说明数据的内容。举例,320 x 240 24-bit RGB的视频是一个类型,44.1-kilohertz(kHZ) 16-bit stereo PCM的音频是另外一种类型。媒体类型是被描述使用DMO_MEDIA_TYPE的结构。在Client能处理任何数据之前,它必须在DMO上为任何的流设置媒体类型。

 

Buffers(缓存)

 

在默认的DMO模型里,client分配各个输入缓存和输出缓存。它填充数据至输入缓存然后递送它们至DMO处,接着DMO写入新的数据至输出缓存中。

 

自由地,一个DMO能支持“in-place”处理。通过“in-place”处理,DMO将输出缓存直接写入到输入缓存中,跳过初始数据。“in-place”处理消除了为个各个缓存分配的缓存的需求。在另一方面,它改变了初始数据,这一点并不能被一些应用程序所接收。

 

默认缓存模型(non-in-place)被IMediaObjec接口所支持。所有的DMOs必须实现这个接口。如果一个DMO支持“in-place”处理,它也有IMediaObjectInPlace接口。则那个Client被要求分配所有缓存,包括输入与输出。

 

使用DMOs

This section describes how to use DMOs. It contains the following topics.

这部分描述如何使用DMOs。它包括如下主题:

直接使用DMO

DirectShow中使用DMOs

 

直接使用DMO

 

这部分描述一个应用程序怎样实现一个直接的DMOclient。应用程序递送输入至DMODMO创建输出,然后应用程序使用这个输出去绘制,更进一步处理或者其它处理。应用程序要负责一些问题,如内存分配,同步和线程问题。这些要求取决于应用程序的种类。

 

假如你正在写一个组件用于一个层在一个应用程序和一个DMO之间(举例,一个ActiveX控件使用一个DMO),这部分的信息同样适合你。更进一步讲,如果你正在写一个DMO,你应当阅读这部分内容,因为这部分内容描述了你的DMO必须实现的功能。

 

这部分内容包括如下主题:

 

设置DMOMedia Types(媒体类型)

DMO的数据处理

DMOIn-Place处理(In-Place processing

DMO的自由流处理(Optional Streams

IMediaBufferr的实现

 

设置DMOMedia Types(媒体类型)

 

DMO能处理数据之前,client必须为任何流设置media type(媒体类型)(有一个局部例外:查看Optional Streams(自由流))。为了寻找流的索引数,可以访问ImediaObject::GetStreamCount方法:

 

DWORD cInput = 0, cOutput = 0;

pDMO->GetStreamCount(&cInput, &cOutput);

 

这个方法返回两个值,输入的数与输出的数。这些值始终被固定在DMO中。

 

Preferred Types(优先选择类型)

 

对于每个流,DMO分配一个可能的媒体类型列表,按照优先选择的顺序。举个例子,preferred type可能是32-RGB24-bit RGB16-bitRGB的顺序。当client设置媒体类型时,它能使用这些序列作为提示。为流检索一个preferred type,访问IMediaObject::GetInputType方法或IMediaObject::GetOutputType方法。为一个类型(开始于0)指定流的数和一个索引值。举例,下面的代码从第一个输入流中检索第一个preferred type

 

DMO_MEDIA_TYPE mt

hr = pDMO->GetInputType(0, 0, &mt)

if (SUCCEEDED(hr))

{

    // Examine this media type (not shown).

    /* ... */

 

    // Free the format block.

    MoFreeMediaType(&mt);

}

 

从一个给定的流中枚举所有的preferred media types,可以使用一个循环通过增量类型索引直到方法返回DMO_E_NO_MORE_ITEMS,如下面的例子:

 

DMO_MEDIA_TYPE mt;

DWORD dwType = 0;

while (hr = pDMO->GetInputType(0, dwType, &mt), SUCCEEDED(hr))

{

    // Examine this media type (not shown).

    /* ... */

 

    // Free the format block.

    MoFreeMediaType(&mt);

    ++dwType;

}

 

你应当注意下面几个关于preferred types的注意点

 

DMO可以返回一个类型没有format块。举例,一个DMO可以指定一个video类型,例如24-bitRGB,没有提供图像的宽和高。当你设置一个类型的时候,你必须提供一个完整的format块(当然,有些媒体类型除外,比如MIDI,从不要求一个format块,由于这个并不适用)。

DMO并不被要求支持返回的每个联合的preferred types。举例,假如一个DMO有两个流,并且每个流有4preferred类型,有16个可能的联合,但是,它们并不是所有都确保是正确的。

client为一个流设置媒体类型时,DMO可能会为其它的流表示一个新的状态而更新preferred types。它并不要求这样做。而一些流,DMO可能不提供任何的preferred types。具有代表性地,一个DMO应当为一些流至少提供一些preferred types

DMO不被要求去提供一个它接受的完全的列表。有可能DMO支持“unadvertisedtypes,但是不当成preferred types来提供。

简而言之,client应当仅仅将preferred types视为指导方向。唯一能知道其中某种类型被支持的方法就是去测试它们,这个会在下个部分去描述。

 

为一个流设置媒体类型

 

使用IMediaObject::SetInputTypeIMediaObject::SetOutputType方法为任何一个流设置媒体类型。你必须提供一个包涵完整媒体类型的描述的DMO_MEDIA_TYPE结构。下面的例子使用44.1-kHz 16-bit stereo PCM audioinput stream 0上设置媒体类型。

 

DMO_MEDIA_TYPE mt;

ZeroMemory(&mt, sizeof(DMO_MEDIA_TYPE));

// Allocate memory for the format block.

HRESULT hr = MoInitMediaType(&mt, sizeof(WAVEFORMATEX));

if (SUCCEEDED(hr))

{

    // Set the type GUIDs.

    mt.majortype  = MEDIATYPE_Audio;

    mt.subtype    = MEDIASUBTYPE_PCM;

    mt.formattype = FORMAT_WaveFormatEx;

 

    // Initialize the format block.

    WAVEFORMATEX *pWave = reinterpret_cast<WAVEFORMATEX*>(mt.pbFormat);

    pWave->wFormatTag = WAVE_FORMAT_PCM;

    pWave->nChannels = 2;

    pWave->nSamplesPerSec = 44100;

    pWave->wBitsPerSample = 16;

    pWave->nBlockAlign = (pWave->nChannels * pWave->wBitsPerSample) / 8;

    pWave->nAvgBytesPerSec = pWave->nSamplesPerSec * pWave->nBlockAlign;

    pWave->cbSize = 0;

 

    // Set the media type.

    hr = pDMO->SetInputType(0, &mt, 0);

 

    // Release the format block.

    MoFreeMediaType(&mt);

}

 

对于一个还没有设置的媒体类型,需要测试它,使用DMO_SET_TYPE_TEST_ONLY标志访问SetInputType或者SetOutputType来测试这个类型是否被接受。如果这个类型被接受,这个方法返回S_OK,否则返回S_FALSE

 

if (S_OK == pDMO->SetInputType(0, &mt, DMO_SET_TYPEF_TEST_ONLY)

{

    // Media type is OK.

}

 

由于对一个流进行设置能影响到另一个流,你也许需要清空一个流的媒体类型。可以这样做,使用DMO_SET_TYPEF_CLEAR标志访问SetInputType或者SetOutputType来进行清空。

 

对于一个decoder DMOclient将首先设置input type,然后选择一个output type。而对于一个encoder DMOclient将首先设置output type,然后才是input type

 

DMO的数据处理

 

这部分解释了如何使用DMO去处理一个数据流。这部分列举了默认状态的步骤。所有DMOs必须支持的方法都在这里描述了。这些方法为输入和输出使用单独的缓存。一些DMOs同样支持in-place processing,使用一个简单的缓存。关于in-place的详细信息,请看In-Place Processing

分配缓存

 

client负责为所有的缓存进行分配。在你对DMO设置了媒体类型后,将要查询DMO为每个流的分配请求。这些能改变主要依靠媒体类型。对于每个流,可以访问IMediaObject::GetInputSizeInfo或者 IMediaObject::GetOutputSizeInfo方法。这些方法将返回下面的信息:

最小缓存大小,以字节形式

Alignment requirements, if any. A buffer is aligned if the start address is a multiple of some specified integer.

将适用于lookaheadDMO的最大数据统计数量。这上数字仅仅适用于输入流(input streams)。对于一些多样的数据(如,MPEG encoding),一个DMO也许需要为流的后期作出考虑。lookahead值指明了在它产生输出之前,DMO将需要多少输入数据。

client必须分配缓存来匹配这些需求。更进一步讲,DMO可能有关于client怎样打包输入数据需要。举例,DMO可能需要每个缓存包涵正确的一个例子(或者video frame)。为了确定这些需要,可以访问IMediaObject::GetInputStreamInfo方法。这个IMediaObject::GetOutputStreamInfo方法返回相似的输出流信息。

在这个默认的流模型里,client不能传递原始缓存指针给DMO。代替的是,它使用一个轻量级的COM对象(可见的接口IMediaBuffer)。IMediaBuffer接口为一个内存块扮演了 COM wrapper功能。因为它是一个COM对象,它支持访问统计(reference counting),这将有利于确认缓存没有被释放而仍然在使用。

注意:IMediaBuffer接口提供的一个功能类似于DirectShow里的IMediaSample接口。

client必须实现IMediaBuffer对象。要查看详情,查看ImplementingIMediaBuffer

 

数据处理

处理数据,要做以下几步:

1、 为每个输入流,填充一个输入数据缓存

2、 访问来IMediaObject::ProcessInput传递每个缓存

3、 访问IMediaObject::ProcessOutput来处理数据。这个方法带来一个缓存数组,都是输出流

4、 重复执行直到没有输入数据

ProcessInput方法每次接受一个流输入。这个方法立即返回,而且DMOIMediaBuffer对象上保持一个参考数。它处理完所有的缓存里的数据后,或者当DMO被应用程序flush的时候释放IMediaBuffer对象。不要再用DMO已经释放掉的一个缓存。为了确定一个输入流是否能接收更多数据,可以访问IMediaObject::GetInputStatus方法。如果那个流能接受更多输入,则这个方法返回DMO_INPUT_STATUSF_ACCEPT_DATA标志。

ProcessOutput方法立即为所有的输出流生成输出。应用程序传送在DMO_OUTPUT_DATA_BUFFER结构数组里,任何一个输出流。(The application passes in an array of DMO_OUTPUT_DATA_BUFFER structures, one for each output stream.)每个数据里的结构有一个指向IMediaBuffer对象的指针。DMO能向缓存中写入尽量多的数据。它同样设置了不同的标志去报告运行的状态。DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE标志指明了DMO能从存在的输入中产生更多的输出。在那个状态下,client能再次访问ProcessOutput。否则,它应当访问ProcessInput来调用再多的输入数据。DMO从不修改那些在输入缓存中的数据。它仅仅将数据写入到输出缓存中。

在你已经将所有的数据递送至一个输入流中之后,访问IMediaObject::Discontinuity方法。在你没处理完剩余的输出(或者flush DMO)的时候,DMO不接受更多的输入到那个流。

At any point after streaming begins),DMO能够接收输入或产生输出或者两者都有。因此,不是GetInputStatus返回DMO_INPUT_STATUSF_ACCEPT_DATA,就是ProcessOutput返回DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE。应用程序要保持数据通顺可以通过测试这些标志和访问ProcessInputProcessOutput的结果。为了中断数据流通,可访问IMediaObject::Flush方法。这个方法使得DMO丢弃任何DMO内部正保持的缓存。


而对于DMO的直接使用,以下几点是要特别注意的。

  1. 在处理数据之前,必须为每条输入输出stream设置media type(Optional stream除外);

  2. 从DMO从获取的media type未必包含format块,但是在给DMO设置media type时,务必带上这部分信息(MIDI除外);

  3. 应用程序必须自己负责分配数据缓存。缓存的大小可以通过调用DMO的IMediaObject::GetInputSizeInfo或IMediaObject::GetOutputSizeInfo得到。DMO使用的数据缓存也是一个COM对象,支持ImediaBuffer接口,与DirectShow filter的Media Sample类似。

  4. 一般的DMO依次调用IMediaObject::ProcessInput和IMediaObject::ProcessOutput处理数据,In-Place的DMO调用IMediaObjectInPlace::Process处理数据。两套方法不能混用。

  5. 在调用ProcessOutput时,如果返回的标记是DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE,说明数据的数据还没有完全取出,需要再次调用ProcessOutput。

  6. 所有输入数据都已输入完成,应该调用DMO的IMediaObject::Discontinuity方法。

  7. 如果你想中断数据处理流程,调用DMO的IMediaObject::Flush。

  8. 区别两种不同的可丢弃stream,标记分别为DMO_OUTPUT_STREAMF_OPTIONAL和DMO_OUTPUT_STREAMF_DISCARDABLE。注意,后者是要设置media type的。

这篇关于DirectX Media Objects的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1055004

相关文章

JavaScript - Objects

对象定义: let person = {name: {first: "Bob",last: "smith"},age: 32,gender: 'male',interests: ['music', 'skiing'],bio: function () {alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' year

实践 HTML5 的 CSS3 Media Queries

先来介绍下 media,确切的说应该是 CSS media queries(CSS 媒体查询),媒体查询包含了一个媒体类型和至少一个使用如宽度、高度和颜色等媒体属性来限制样式表范围的表达式。CSS3 加入的媒体查询使得无需修改内容便可以使样式应用于某些特定的设备范围。  那么该怎么定义 media 呢,看下面的代码,你肯定能猜出个大概。 <!-- link元素中的CSS媒体查询 --><li

URP custompasscustom render objects

https://dbbh666.blog.csdn.net/article/details/141296728?spm=1001.2014.3001.5502 上一次 custom render pass的时候,直接是quad的渲染,如果想把任意对象绘制到FBO怎么写呢 参考这两个高手的文章,总结一下 https://www.bilibili.com/read/cv6735961/ https:

鸿蒙(API 12 Beta3版)【使用智能PhotoPicker】Media Library Kit媒体文件管理服务

智能PhotoPicker是基于PhotoPicker的高阶功能,可以从大量图片中根据配置的智能推荐参数,快速筛选出符合条件的图片,并在PhotoPicker中推荐给用户选择。 应用拉起PhotoPicker时,可以配置智能推荐参数。当设备中有满足应用传入的智能推荐参数的图片时,PhotoPicker界面除了展示全量的图片外,还会展示符合条件的推荐图片。 选择特定类型([Recommenda

skimage包的小优化(2):模仿remove_small_objects()函数保留图片中连通域最大的区域

python模仿remove_small_objects()函数保留图片中连通域最大的区域 skimage包的morphology子模块中,提供了一个remove_small_objects()函数,可以通过自己设定的连通域面积阈值有效去掉图片中的噪点,但是在具体使用过程中会发现:这个函数使用起来还有诸多的不便,好在这个函数的源代码并不长,在在skimage包的小优化(1):模仿remove_s

【JavaScript】SpringMVC Http请求415 Unsupported Media Type的问题

需要在请求$ajax请求头部增加 contentType: "application/json; charset=utf-8", 例如: function sendEmailToCandidate(id) {console.log(id);var params = {};params["vars"] = {"formId": id};params["tableMap"] = {

error:loading /system/media/audio/ui/Effect_Tick.ogg

error loading /system/media/audio/ui/Effect_Tick.ogg  问题原因:      同一个AVD,调试了很多个项目,产生了N多个log文件,这些文件可能产生了影响。 解决办法:     新建一个AVD即可。 AVD的全称为:Android Virtual Device, 就是Android运行的虚拟设备,他是Android的模拟器识别。

专业视频编辑和制作软件Adobe Media Encoder(ME)win/mac下载安装和软件介绍

一、软件概述 1.1 软件简介 Adobe Media Encoder(ME)是由Adobe公司开发的一款专业视频编辑和制作软件,全称为Media Encoder,是Creative Cloud套件中的一个重要组件。Adobe ME以其强大的视频编码、转码、调整、剪辑、合成等功能,深受专业视频制作人员、视频制片人和爱好者的喜爱。 1.2 主要功能 视频编辑与管理:提供剪辑、切割、分层、抽取

Veritas NBU8.3.0.2安装Media Server(篇三)

一、环境自检阶段 1、Media角色地址为192.168.189.3,计算机名称为bakmedia,域名为sszz.com 2、防火墙均已关闭 二、hosts解析配置 在安装之前需要在hosts文件中配置解析,master和media都需要配置;后期如果备份客户端也需要为客户端添加配置 IP地址                计算机名称                计算机全

Apple - Media Playback Programming Guide

本文翻译整理自:Media Playback Programming Guide(Updated: 2018-01-16 https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/MediaPlaybackGuide/Contents/Resources/en.lproj/Introduction