我的Media Foundation应用程序中有一个IMFSampleGrabberSinkCallback
,我创建了一个使用MFCreateSampleGrabberSinkActivate
的激活器。该函数仅接收部分填充的媒体类型。在示例抓取器回调中,NVENC编码器正在运行(我知道NVENC有开箱即用的转换,但该软件未在Windows 10上运行)。为了使用编码器,我需要具有拓扑分辨后的完整媒体类型(主要是帧的大小,在创建样本采集器时不知道)。
似乎没有明显的方法可以在IMFSampleGrabberSinkCallback
中获取此信息,因此我的想法是在收到MF_TOPOSTATUS_READY
后从会话中获取完整拓扑。
第一个问题:这是获取抓取器会收到的完整类型的唯一方法,还是我错过了什么?
获得完整拓扑后,我们的想法是迭代所有节点,使用样本采集器搜索一个节点并检索其输入类型。
第二个问题:最好的方法是什么?对我来说,似乎无法从拓扑节点中检索我的IMFSampleGabberSinkCallback
。
我会使用topo节点ID解决这个问题,但我不确定这是否适用于任何情况。 IMFTopologyNode::GetTopoNodeID
的文档说明了
首次创建节点时,会为其分配一个标识符。节点标识符在拓扑中是唯一的,但可以在多个拓扑中重用。拓扑加载器使用标识符来查找先前拓扑中的节点,以便它可以重用先前拓扑中的对象。
对我而言,目前尚不清楚ID 是否可以重复使用,还是可以重复使用。
第三个问题:是否可以保证,如果我获取节点的拓扑节点ID,我会插入从IMFActivate
获取的MFCreateSampleGrabberSinkActivate
(并且只要我这样做)不使用IMFTopologyNode::SetTopoNodeID
手动更改ID,在拓扑解析过程中创建的任何后续拓扑都将使用相同的ID?
提前致谢, 克里斯托弗
编辑:问题不在于如何让NVENC正常工作并解决其输入类型,但关键问题是(1)是否保证 topo ID得以保留在解决过程中以及(2)是否有更好的方法来做到这一点(易于用户主动更改topo ID):首先,我为抓取器回调创建一个激活器。一旦我将包含激活器的节点作为对象添加到拓扑中,我就会检索其ID。当会话报告拓扑已准备就绪时,我检索具有之前保存的ID的节点,获取其对象,查询其IMFStreamSink
接口,检索其IMFMediaTypeHandler
,获取当前媒体类型并获取实际NVENC的帧大小和帧速率。但是:这仅在ID无法更改且未主动更改时才有效。
我从测试代码中提取了拓扑解析阶段:
拓扑解析器发现需要进行颜色转换,并添加蓝色转换以解决此问题。回到问题:在这种情况下,它们将是(1)是否保证红色节点的ID在解决期间不能改变,以及(2)是否有另一种方法来实现这一点,这对某人不敏感在红色节点上使用IMFTopologyNode::SetTopoNodeID
。
答案 0 :(得分:0)
根据我的经验,拓扑节点的ID看起来像散列函数的结果。我认为ID的生成器具有复杂的算法,并且它不能保证从一个会话到另一个会话的常量,但ID在当前会话期间是稳定的。也许你可以尝试另一种方式 - 你写的 - “已经将包含激活器的节点添加为拓扑的对象,”但是你如何处理“我的抓取器回调的激活器”上的原始指针? IMFTopologyNode::SetObject
增加IUnknown的引用。我认为你释放原始指针一个激活,但你
可以将指针放在“我的抓取器回调的激活器”上。在这种情况下,不需要 - “我检索之前保存的ID的节点,获取其对象”。解析拓扑后,ALREADY可以在激活器上使用完全解析的MediaType指针并查询其IMFStreamSink
接口,检索其IMFMediaTypeHandler
而不保存拓扑节点的ID。
Activator是代理,但对于IMFMediaSink
对象,可通过IMFActivate::ActivateObject
调用IID_IMFMediaSink
来获取。虽然它是第一次通过拓扑解析调用它创建具有IMFMediaSink
接口的对象(在激活器中创建IMFStreamSink
并且IMFSampleGabberSinkCallback
内部本身),但下一次调用将返回引用 - Activator KEEPS解析IMFMediaSink
上的引用 - 根据MSDN MFActivate::ActivateObject - “在第一次调用ActivateObject之后,后续调用返回指向同一实例的指针,直到客户端调用ShutdownObject或IMFActivate::DetachObject
。”这意味着在解析拓扑之后,Microsoft的代码不会分离对象或关闭它 - 只关闭会话执行ShutdownObject或IMFActivate::DetachObject
。
此致