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

Should I release the returned IMFSample of an internally allocated MFT output buffer?

媒体基础转换对象 (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

Pointer to the IMFSample interface. Before calling ProcessOutput, set this member equal to a valid IMFSample pointer or NULL. See Remarks for more information.

来自 IMFTransform::ProcessOutput 文档:

输出缓冲区

The MFT returns output data for a stream through the pSample member of the MFT_OUTPUT_DATA_BUFFER structure. This structure member is a pointer to the IMFSample interface of a media sample. (See Media Samples.) The media sample is allocated either by the caller or by the MFT, depending on the MFT's allocation model. To find the allocation model, call IMFTransform::GetOutputStreamInfo and examine the dwFlags member of the MFT_OUTPUT_STREAM_INFO structure

...

If pSample is NULL and dwFlags does not contain the MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER, the MFT provides a sample for the output data. The MFT sets pSample to point to the sample that it provides. The MFT can either allocate a new sample or re-use an input sample.

文档中没有提到是否应该释放这种情况下返回的IMFSample接口。似乎不​​是这样,因为文档非常明确通过同一结构返回的任何事件都应由调用者释放。

来自 MFT_OUTPUT_DATA_BUFFER structure 文档:

pEvents

Before calling ProcessOutput, set this member to NULL. On output, the MFT might set this member to a valid IMFCollection interface pointer. The pointer represents a collecton that contains zero or more events. To get each event, call IMFCollection::GetElement and query the returned IUnknown pointer for the IMFMediaEvent interface. When the ProcessOutput method returns, the caller is responsible for releasing the IMFCollection pointer if the pointer is not NULL.

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

我认为如果我们不应该释放返回的接口,它应该被明确地记录下来,因为它违背了我们使用完后释放接口的既定 COM 方式。

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

下面的代码片段适用于所有三种模型:

  • If the MFT_OUTPUT_STREAM_PROVIDES_SAMPLES flag is present, the MFT allocates the media sample.
  • If the MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES flag is present, the caller can optionally provide a media sample. If pSample is NULL, the MFT will allocate the media sample.
  • If neither of these two flags is present, the caller must allocate the media sample.

请注意,文档中没有提到调用方提供示例指针,MFT 将其替换为自己的示例指针的场景。

(虽然代码并不完美,只是参考计数的一个例子;如果有 先验 样本是调用者的信息,那么就没有必要做 Attach/Detach 事情,当然)

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