确定已解析的 IMFSampleGrabberSinkCallback 输入类型
Determine resolved input type of IMFSampleGrabberSinkCallback
我的 Media Foundation 应用程序中有一个 IMFSampleGrabberSinkCallback
,我创建了一个使用 MFCreateSampleGrabberSinkActivate
的激活器。该函数仅接收部分填充的媒体类型。在样本采集器回调中,NVENC 编码器是 运行(我知道 NVENC 有开箱即用的转换,但软件不是 运行 on Windows 10) .为了使用编码器,我需要拥有拓扑解析后的完整媒体类型(主要是帧的大小,创建样本采集器时不知道)。
似乎没有明显的方法可以在 IMFSampleGrabberSinkCallback
中获取此信息,所以我的想法是在收到 MF_TOPOSTATUS_READY
后从会话中获取完整的拓扑。
第一个问题:这是获取抓取器将收到的完整类型的唯一方法还是我错过了什么?
获得完整拓扑后,我们的想法是迭代所有节点,使用样本采集器搜索节点并检索其输入类型。
第二个问题:最好的方法是什么?对我来说,似乎没有办法从拓扑节点中检索我的IMFSampleGabberSinkCallback
。
我会使用拓扑节点 ID 解决这个问题,但我不确定这在任何情况下是否都有效。 IMFTopologyNode::GetTopoNodeID
的文档指出
When a node is first created, it is assigned an identifier. Node identifiers are unique within a topology, but can be reused across several topologies. The topology loader uses the identifier to look up nodes in the previous topology, so that it can reuse objects from the previous topology.
对我来说,不清楚 ID 是否会 被重复使用,或者它是否 可以 被重复使用。
第三个问题:是否可以保证,如果我获得节点的拓扑节点ID,我插入从MFCreateSampleGrabberSinkActivate
获得的IMFActivate
(并且只要我不使用 IMFTopologyNode::SetTopoNodeID
手动更改 ID,在拓扑解析过程中创建的任何后续拓扑都会使用相同的 ID?
提前致谢,
克里斯托夫
编辑:问题不在于如何让 NVENC 工作并解析其输入类型,而是关键问题是 (1) topo ID 是否保证在解析过程中被保留 并且(2)是否有比以下更好的方法(这容易受到用户主动更改 topo ID 的影响):首先,我创建一个激活器我的抓取器回调。将包含激活器的节点作为对象添加到拓扑后,我将检索其 ID。当session报topology ready时,我检索之前保存的ID的节点,获取其对象,查询其IMFStreamSink
接口,检索其IMFMediaTypeHandler
,获取当前媒体类型并获取实际NVENC 的帧大小和帧速率。但是:这仅在 ID 无法更改且未主动更改时有效。
我已经从我的测试代码中提取了拓扑解析阶段:
拓扑解析器发现需要进行颜色转换并添加蓝色转换来解决这个问题。回到问题:在这种情况下,它们将是 (1) 是否保证红色节点的 ID 在解析过程中不会更改,以及 (2) 是否有其他人无法实现的替代方法在红色节点上使用 IMFTopologyNode::SetTopoNodeID
。
根据我的经验,拓扑节点的 ID 看起来像是哈希函数的结果。我认为 ID 生成器具有复杂的算法,它不能保证从一个会话到另一个会话保持不变,但 ID 在当前会话期间是稳定的。也许你可以尝试另一种方式 - 你写的 - "have added the node containing the activator as object to the topology," 但是你如何处理 "an activator for my grabber callback" 上的原始指针? IMFTopologyNode::SetObject
递增 IUnknown 的引用。我认为你释放了原始指针并激活了,但是你
可以将指针保持在 "an activator for my grabber callback" 上。在那种情况下就不需要-"I retrieve the node with the ID saved before, obtain its object,"。解析拓扑后,您已经可以在具有完全解析的 MediaType 的激活器上拥有指针并查询其 IMFStreamSink
接口,检索其 IMFMediaTypeHandler
而不保存拓扑节点的 ID。
Activator 是代理,但是对于 IMFMediaSink
对象,它是通过调用 IMFActivate::ActivateObject
和 IID_IMFMediaSink
获得的。虽然它是通过拓扑解析第一次调用的,但它会在激活器中创建具有 IMFMediaSink
接口的对象(它创建具有 IMFSampleGabberSinkCallback
内部的 IMFStreamSink
对象),但下一次调用将 return参考 - Activator KEEPS 参考已解决 IMFMediaSink
- 根据 MSDN MFActivate::ActivateObject - "After the first call to ActivateObject, subsequent calls return a pointer to the same instance, until the client calls either ShutdownObject or IMFActivate::DetachObject
." 这意味着在解决拓扑后 Microsoft 的代码不会分离对象或关闭它 - 仅关闭会话执行 ShutdownObject 或IMFActivate::DetachObject
.
此致
我的 Media Foundation 应用程序中有一个 IMFSampleGrabberSinkCallback
,我创建了一个使用 MFCreateSampleGrabberSinkActivate
的激活器。该函数仅接收部分填充的媒体类型。在样本采集器回调中,NVENC 编码器是 运行(我知道 NVENC 有开箱即用的转换,但软件不是 运行 on Windows 10) .为了使用编码器,我需要拥有拓扑解析后的完整媒体类型(主要是帧的大小,创建样本采集器时不知道)。
似乎没有明显的方法可以在 IMFSampleGrabberSinkCallback
中获取此信息,所以我的想法是在收到 MF_TOPOSTATUS_READY
后从会话中获取完整的拓扑。
第一个问题:这是获取抓取器将收到的完整类型的唯一方法还是我错过了什么?
获得完整拓扑后,我们的想法是迭代所有节点,使用样本采集器搜索节点并检索其输入类型。
第二个问题:最好的方法是什么?对我来说,似乎没有办法从拓扑节点中检索我的IMFSampleGabberSinkCallback
。
我会使用拓扑节点 ID 解决这个问题,但我不确定这在任何情况下是否都有效。 IMFTopologyNode::GetTopoNodeID
的文档指出
When a node is first created, it is assigned an identifier. Node identifiers are unique within a topology, but can be reused across several topologies. The topology loader uses the identifier to look up nodes in the previous topology, so that it can reuse objects from the previous topology.
对我来说,不清楚 ID 是否会 被重复使用,或者它是否 可以 被重复使用。
第三个问题:是否可以保证,如果我获得节点的拓扑节点ID,我插入从MFCreateSampleGrabberSinkActivate
获得的IMFActivate
(并且只要我不使用 IMFTopologyNode::SetTopoNodeID
手动更改 ID,在拓扑解析过程中创建的任何后续拓扑都会使用相同的 ID?
提前致谢, 克里斯托夫
编辑:问题不在于如何让 NVENC 工作并解析其输入类型,而是关键问题是 (1) topo ID 是否保证在解析过程中被保留 并且(2)是否有比以下更好的方法(这容易受到用户主动更改 topo ID 的影响):首先,我创建一个激活器我的抓取器回调。将包含激活器的节点作为对象添加到拓扑后,我将检索其 ID。当session报topology ready时,我检索之前保存的ID的节点,获取其对象,查询其IMFStreamSink
接口,检索其IMFMediaTypeHandler
,获取当前媒体类型并获取实际NVENC 的帧大小和帧速率。但是:这仅在 ID 无法更改且未主动更改时有效。
我已经从我的测试代码中提取了拓扑解析阶段:
拓扑解析器发现需要进行颜色转换并添加蓝色转换来解决这个问题。回到问题:在这种情况下,它们将是 (1) 是否保证红色节点的 ID 在解析过程中不会更改,以及 (2) 是否有其他人无法实现的替代方法在红色节点上使用 IMFTopologyNode::SetTopoNodeID
。
根据我的经验,拓扑节点的 ID 看起来像是哈希函数的结果。我认为 ID 生成器具有复杂的算法,它不能保证从一个会话到另一个会话保持不变,但 ID 在当前会话期间是稳定的。也许你可以尝试另一种方式 - 你写的 - "have added the node containing the activator as object to the topology," 但是你如何处理 "an activator for my grabber callback" 上的原始指针? IMFTopologyNode::SetObject
递增 IUnknown 的引用。我认为你释放了原始指针并激活了,但是你
可以将指针保持在 "an activator for my grabber callback" 上。在那种情况下就不需要-"I retrieve the node with the ID saved before, obtain its object,"。解析拓扑后,您已经可以在具有完全解析的 MediaType 的激活器上拥有指针并查询其 IMFStreamSink
接口,检索其 IMFMediaTypeHandler
而不保存拓扑节点的 ID。
Activator 是代理,但是对于 IMFMediaSink
对象,它是通过调用 IMFActivate::ActivateObject
和 IID_IMFMediaSink
获得的。虽然它是通过拓扑解析第一次调用的,但它会在激活器中创建具有 IMFMediaSink
接口的对象(它创建具有 IMFSampleGabberSinkCallback
内部的 IMFStreamSink
对象),但下一次调用将 return参考 - Activator KEEPS 参考已解决 IMFMediaSink
- 根据 MSDN MFActivate::ActivateObject - "After the first call to ActivateObject, subsequent calls return a pointer to the same instance, until the client calls either ShutdownObject or IMFActivate::DetachObject
." 这意味着在解决拓扑后 Microsoft 的代码不会分离对象或关闭它 - 仅关闭会话执行 ShutdownObject 或IMFActivate::DetachObject
.
此致