IMFTransform::P rocessOutput 方法 (mftransform.h)

从当前输入数据生成输出。

语法

HRESULT ProcessOutput(
  [in]      DWORD                  dwFlags,
  [in]      DWORD                  cOutputBufferCount,
  [in, out] MFT_OUTPUT_DATA_BUFFER *pOutputSamples,
  [out]     DWORD                  *pdwStatus
);

参数

[in] dwFlags

_MFT_PROCESS_OUTPUT_FLAGS枚举中零个或多个标志的按位 OR

[in] cOutputBufferCount

pOutputSamples 数组中的元素数。 该值必须至少为 1。

[in, out] pOutputSamples

指向由调用方分配的 MFT_OUTPUT_DATA_BUFFER 结构的数组的指针。 MFT 使用此数组将输出数据返回给调用方。

[out] pdwStatus

_MFT_PROCESS_OUTPUT_STATUS枚举接收零个或多个标志的按位 OR

返回值

该方法返回 HRESULT。 可能的值包括(但并不限于)下表中的项。

返回代码 说明
S_OK
方法成功。
E_UNEXPECTED
ProcessOutput 方法是在不需要此方法调用的异步 MFT 上调用的。
MF_E_INVALIDSTREAMNUMBER
一个或多个MFT_OUTPUT_DATA_BUFFER结构的 dwStreamID 成员中的流标识符无效。
MF_E_TRANSFORM_NEED_MORE_INPUT
转换在接收更多输入数据之前无法生成输出数据。
MF_E_TRANSFORM_STREAM_CHANGE
输出流的格式已更改,或者有新的首选格式,或者有新的输出流。
MF_E_TRANSFORM_TYPE_NOT_SET
必须在一个或多个 MFT 流上设置媒体类型。
 
注意 如果要将 DirectX 媒体对象 (DMO) 转换为 MFT,请注意 ,S_FALSE 不是 IMFTransform::P rocessOutput 的有效返回代码,这与 IMediaObject::P rocessOutput 方法不同。
 

注解

pOutputSamples 数组的大小必须等于或大于所选输出流的数量。 所选输出流的数量等于输出流的总数减去 取消选择 的流数。 如果流具有 MFT_OUTPUT_STREAM_OPTIONAL 标志,并且调用方未 (设置媒体类型或将媒体类型设置为 NULL) ,则会取消选择该流。 有关详细信息,请参阅 _MFT_OUTPUT_STREAM_INFO_FLAGS 枚举。

此方法生成输出示例,还可以生成事件。 如果方法成功,则至少满足以下条件之一:

  • pOutputSamples 数组中的一个或多个示例包含输出数据。
  • pOutputSamples 数组的一个或多个成员包含非空事件集合。
如果在包括 Mftransform.h 之前定义了 MFT_UNIQUE_METHOD_NAMES ,则此方法将重命名为 MFTProcessOutput。 请参阅 创建混合 DMO/MFT 对象

输出缓冲区

MFT 通过 MFT_OUTPUT_DATA_BUFFER 结构的 pSample 成员返回流的输出数据。 此结构成员是指向媒体示例的 IMFSample 接口的指针。 (请参阅 媒体示例。) 媒体示例由调用方或 MFT 分配,具体取决于 MFT 的分配模型。 若要查找分配模型,请调用 IMFTransform::GetOutputStreamInfo 并检查MFT_OUTPUT_STREAM_INFO结构的 dwFlags 成员:
  • 如果 存在MFT_OUTPUT_STREAM_PROVIDES_SAMPLES 标志,则 MFT 会分配媒体示例。
  • 如果 存在MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES 标志,则调用方可以选择提供媒体示例。 如果 pSampleNULL,MFT 将分配媒体示例。
  • 如果这两个标志都不存在,则调用方必须分配媒体示例。
除非输出流的媒体类型发生更改,否则这些标志保持不变。

如果调用方分配媒体示例,则媒体示例必须包含足以容纳输出数据的缓冲区。 若要查找缓冲区要求,请调用 GetOutputStreamInfo。 MFT 将输出数据写入缓冲区的开头,覆盖缓冲区中已存在的任何数据。

如果 MFT 分配示例,则 MFT 还会为示例分配缓冲区。

如果 MFT 具有多个输出流,则流可能会以不同的速率生成输出,因此某些流可能具有输出,而其他流则不具有输出。 如果流未生成任何输出,则 MFT 在 MFT_OUTPUT_DATA_BUFFER 结构的 dwStatus 成员中为该流设置 MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE 标志。 在这种情况下,如果调用方分配了 pSample,则示例中的缓冲区不包含任何有效数据。 如果调用方未分配 pSample则MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE 标志指示 pSample 在方法返回后仍等于 NULL

如果没有输出流具有数据,并且 MFT 没有要返回的事件,则 ProcessOutput 将返回 MF_E_TRANSFORM_NEED_MORE_INPUT

MFT 不能在对 ProcessOutput 的单个调用中为每个流返回多个样本。 如果在 ProcessOutput 返回后流有更多的输出数据可用,MFT 将在该流的 MFT_OUTPUT_DATA_BUFFER 结构的 dwStatus 成员中设置 MFT_OUTPUT_DATA_BUFFER_INCOMPLETE 标志。

如果 MFT 有足够的数据来生成输出,则应拒绝接受任何其他输入,直到 ProcessOutput 被调用足够多的时间来拉取所有可用输出。 (当 IMFTransform::GetOutputStreamInfo 方法返回 MFT_OUTPUT_STREAM_LAZY_READ flag.) 通常,具有多个输出流的 MFT 应尽快为流生成输出,而不是等待所有流具有输出。

带内事件

MFT 可以在每个MFT_OUTPUT_DATA_BUFFER结构的 pEvents 成员中返回事件对象的集合。 MFT 分配集合对象和事件。

若要向调用方发送事件,MFT 在 ProcessOutput 中执行以下步骤:

  1. 通过调用 MFCreateCollection 创建新的集合对象。
  2. 通过调用 IMFCollection::AddElement 将一个或多个事件添加到集合中。
  3. MFT_OUTPUT_DATA_BUFFER 结构的 pEvents 成员设置为等于 IMFCollection 指针。 MFT 在此接口上留下引用计数;调用方必须释放指针。
事件没有时间戳。 调用方应在处理输出示例之前处理事件。 换句话说,事件发生在流中的点,紧接在对 ProcessOutput 的上一次调用之后,以及从当前 ProcessOutput 调用返回的任何输出样本之前。

ProcessOutput 方法返回一个或多个事件和零个输出样本是有效的。

调用方负责释放 MFT 分配的任何事件。 方法返回时,检查每个MFT_OUTPUT_DATA_BUFFER结构的 pEvents 成员。 如果值不为 NULL,调用方必须释放 IMFCollection 接口指针:

// Release the events that an MFT might allocate in IMFTransform::ProcessOutput().
void ReleaseEventCollection(DWORD cOutputBuffers, MFT_OUTPUT_DATA_BUFFER* pBuffers)
{
    for (DWORD i = 0; i < cOutputBuffers; i++)
    {
        if (pBuffers[i].pEvents)
        {
            pBuffers[i].pEvents->Release();
            pBuffers[i].pEvents = NULL;
        }
    }
}

MFT 不应使用 IMFMediaEventGenerator 接口发送带内事件。

Stream更改

ProcessOutput 方法可能会导致输出流中的以下任何更改:
  • 删除输出流。 为了发出删除流的信号,MFT 在 MFT_OUTPUT_DATA_BUFFER 结构的 dwStatus 成员中为该流设置 MFT_OUTPUT_DATA_BUFFER_STREAM_END 标志。
  • 创建新的输出流。 为了向新的输出流发出信号,MFT 在 pdwStatus 参数中设置MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS标志。 新流可以具有与已删除流相同的流标识符。
  • 输出流上的格式更改。 为了指示格式更改,MFT 在 MFT_OUTPUT_DATA_BUFFER 结构的 dwStatus 成员中为该流设置 MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE 标志。
所有这三个操作都可能是由对 ProcessOutput 的单个调用导致的。 调用方必须按此处列出的顺序响应它们-首先删除,然后添加,然后更改格式。

MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE标志指示输出流上的格式更改。 这可能意味着当前媒体类型已无效,或者首选项顺序已更改,并且提供了更高效的格式。 在后一种情况下,客户端可能会重新设置原始媒体类型。 为了防止无休止的循环,MFT 不应再次设置 MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE 标志,直到发生另一个更改。 此外,如果首选项顺序发生更改,但当前媒体类型仍然是首选类型,请避免设置此标志。

示例属性

输入示例可能具有通过 IMFAttributes 接口访问的属性。 除非不再应用特定属性,否则所有属性都应复制到相应的输出示例中。 复制属性的责任确定如下:
  • 如果 MFT 上的 MFPKEY_EXATTRIBUTE_SUPPORTED 属性值 为 VARIANT_TRUE,则 MFT 将复制属性。
  • 如果 MFPKEY_EXATTRIBUTE_SUPPORTED 的值 VARIANT_FALSE或未设置 属性,则客户端必须复制示例属性。 不要覆盖 MFT 在输出示例中设置的任何属性。
有关示例属性的列表,请参阅 示例属性

异步处理

前面的注释描述了 同步 处理模型。 若要支持异步处理,请参阅 异步 MRT

要求

要求
最低受支持的客户端 Windows Vista [桌面应用 | UWP 应用]
最低受支持的服务器 Windows Server 2008 [桌面应用 | UWP 应用]
目标平台 Windows
标头 mftransform.h
Library Mfuuid.lib

另请参阅

IMFTransform

媒体基础转换