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
成员
...
如果
pSample
为NULL
且dwFlags
不包含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方式。
答案 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