我应该释放内部分配的MFT输出缓冲区的返回IMFSample吗?

时间:2016-09-06 17:04:58

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

Media Foundation转换对象(MFT)可以实现输出缓冲区分配模型,其中缓冲区由MFT对象在内部分配。

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

来自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成员

...

  

如果pSampleNULLdwFlags不包含   MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER,MFT提供了一个示例   输出数据。 MFT将pSample设置为指向样本   它提供了。 MFT可以分配新样本或重新使用   输入样本。

文档没有提到是否应该释放在这种情况下返回的IMFSample接口。似乎情况并非如此,因为文档非常清楚,任何事件都是通过调用者应该释放相同的结构。

来自MFT_OUTPUT_DATA_BUFFER structure文档:

  

pEvents

     

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

有人可以确认是否应该发布返回的IMFSample界面吗?

我认为如果我们不应该释放返回的接口,那么应该明确地记录它,因为它违反了我们完成使用后发布接口的既定COM方式。

1 个答案:

答案 0 :(得分:4)

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

以下代码段适用于所有三种型号:

  
      
  • 如果存在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