【问题标题】:Should I release the returned IMFSample of an internally allocated MFT output buffer?我应该释放返回的内部分配的 MFT 输出缓冲区的 IMFSample 吗?
【发布时间】:2017-01-14 05:27:14
【问题描述】:

媒体基础变换对象 (MFT) 可以实现输出缓冲区分配模型,其中缓冲区由 MFT 对象在内部分配。

如果是这种情况,内部分配的缓冲区将通过传递给IMFTransform::ProcessOutput() 方法的MFT_OUTPUT_DATA_BUFFER 结构的pSample 成员返回。

来自MFT_OUTPUT_DATA_BUFFER structure 文档:

typedef struct _MFT_OUTPUT_DATA_BUFFER {
  DWORD         dwStreamID;
  IMFSample     *pSample;
  DWORD         dwStatus;
  IMFCollection *pEvents;
} MFT_OUTPUT_DATA_BUFFER;

pSample

指向IMFSample 接口的指针。在拨打ProcessOutput之前, 将此成员设置为等于有效的IMFSample 指针或NULL。看 备注了解更多信息。

来自IMFTransform::ProcessOutput 文档:

输出缓冲区

MFT 通过pSample 成员返回流的输出数据 MFT_OUTPUT_DATA_BUFFER 结构。该结构成员是 指向媒体样本的IMFSample 接口的指针。 (见媒体 样本。)媒体样本由调用者或 MFT,取决于 MFT 的分配模型。 查找分配 模型,请致电IMFTransform::GetOutputStreamInfo 并检查 dwFlags MFT_OUTPUT_STREAM_INFO 结构的成员

...

如果pSampleNULL 并且dwFlags 不包含 MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER,MFT提供样本 为输出数据。 MFT 设置pSample 指向样本 它提供的。 MFT 可以分配新样本或重新使用 输入样本。

文档没有提到在这种情况下返回的IMFSample 接口是否应该被释放。 似乎情况并非如此,因为文档非常明确地表明任何事件都通过相同的方式返回struct 应该由调用者释放。

来自MFT_OUTPUT_DATA_BUFFER structure 文档:

pEvents

在调用ProcessOutput 之前,将此成员设置为NULL。输出时, MFT 可能会将此成员设置为有效的IMFCollection 接口指针。指针表示一个集合,其中包含 零个或多个事件。要获取每个事件,请致电 IMFCollection::GetElement 并查询返回的IUnknown 指针 对于IMFMediaEvent 接口。 ProcessOutput 方法 返回,调用者负责释放IMFCollection 如果指针不是NULL,则指针。

有人可以确认返回的IMFSample接口是否应该释放?

我认为,如果我们不应该释放返回的接口,则应该明确记录,因为这与我们使用完后释放接口的既定 COM 方式背道而驰。

【问题讨论】:

  • 我确认文档不明确...这种宽松的情况会造成有关 COM 和释放资源的架构问题。

标签: c++ memory-management ms-media-foundation


【解决方案1】:

如果指针被 MFT 初始化为非 NULL 值,则调用者负责释放样本(与调用者分配的缓冲区相反——在这种情况下,MFT 使用它但不需要将其添加到结构)。

下面的代码 sn-p 适用于所有三个模型:

  • 如果存在 MFT_OUTPUT_STREAM_PROVIDES_SAMPLES 标志,则 MFT 分配媒体样本。
  • 如果存在 MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES 标志,调用者可以选择提供媒体样本。如果 pSample 为 NULL,则 MFT 将分配媒体样本。
  • 如果这两个标志都不存在,调用者必须分配媒体样本。

请注意,文档没有提到调用者提供示例指针,而 MFT 将其替换为自己的情况。

(虽然代码并不完美,只是引用计数的说明;如果有先验信息表明样本是调用者的,那么就不需要做附加/分离的事情,当然)

CComPtr<IMFSample> pSample;
// pSample is NULL or not
MFT_OUTPUT_DATA_BUFFER Buffer;
Buffer.pSample = pSample.Detach();
// ...
const HRESULT nResult = pTransform->ProcessOutput(..., &Buffer, ...);
pSample.Attach(Buffer.pSample);
// pSample holds a valid properly ref'fed pointer
// No need to use Buffer.pSample below

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-29
    • 2017-07-27
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多