从 SinkWriter 或 ICodecAPI 或 IMFTransform 获取编码器名称
Posted
技术标签:
【中文标题】从 SinkWriter 或 ICodecAPI 或 IMFTransform 获取编码器名称【英文标题】:Get encoder name from SinkWriter or ICodecAPI or IMFTransform 【发布时间】:2014-01-06 09:07:07 【问题描述】:我正在使用 SinkWriter 以便使用媒体基础对视频进行编码。
初始化 SinkWriter 后,我想获取它使用的底层编码器,并打印出它的名称,这样我就可以看到它使用的编码器。 (就我而言,编码器很可能是 MF 中包含的H.264 Video Encoder)。
我可以获得对编码器的 ICodecAPI 和 IMFTransform 接口的引用(使用 pSinkWriter->GetServiceForStream
),但我不知道如何使用这些接口获取编码器的友好名称。
有谁知道如何从 sinkwriter 获取编码器的友好名称?还是从它的ICodecAPI
或IMFTransform
接口?
【问题讨论】:
还没有人找到对此的回应?这似乎是一件非常基本的事情,至少 GUID 会有所帮助。 【参考方案1】:到目前为止,这是一个有效的解决方案,我不能 100% 确定它是否有效,但可以做的是:
1)在启动时枚举所有可以使用的编解码器(我理解在这种情况下是 H264 编码器)并订阅设置更改事件
MFT_REGISTER_TYPE_INFO TransformationOutput = MFMediaType_Video, MFVideoFormat_H264 ;
DWORD nFlags = MFT_ENUM_FLAG_ALL;
UINT32 nCount = 0;
CLSID* pClsids;
MFTEnum( MFT_CATEGORY_VIDEO_ENCODER, nFlags, NULL, &TransformationOutput, NULL, &pClsids, &nCount);
// Ok here we assume nCount is 1 and we got the MS encoder
ICodecAPI *pMsEncoder;
hr = CoCreateInstance(pClsids[0], NULL, CLSCTX_INPROC_SERVER, __uuidof(ICodecAPI), (void**)&pMsEncoder);
// nCodecIds is supposed to be an array of identifiers to distinguish the sender
hr = pMsEncoder->RegisterForEvent(CODECAPI_AVEncVideoOutputFrameRate, (LONG_PTR)&nCodecIds[0]);
2) 不能 100% 确定在设置流的输入媒体类型时是否还设置了帧速率设置,但无论如何您可以尝试在从 SinkWriter
检索到的 ICodecAPI
上设置相同的属性.然后在获得事件后,您应该能够通过将lParam1
与传递的值进行比较来识别编解码器。但这仍然很糟糕,因为它依赖于所有编码器都支持事件通知这一事实,并且如果我对流构建时生成的事件的假设是错误的,则需要更改不必要的参数。
【讨论】:
【参考方案2】:拥有IMFTransform
您没有编码器的友好名称。
您有一个选项是检查转换输出类型并与众所周知的 GUID 进行比较以识别编码器,特别是您将拥有一个带有 H264 编码器 MFT 的 MFVideoFormat_H264
子类型。
另一种选择是到达编码器的CLSID
(IMFTransform
无法获得它,但您可能会获得它,例如通过IMFActivate
或查询MFT_TRANSFORM_CLSID_Attribute
属性,或通过IPersist*
接口) .然后,您可以在注册表中查找友好名称或枚举转换,并通过比较 CLSID 在该列表中查找您的转换。
【讨论】:
MS H.264 视频编码器没有实现IPersist
,并且不支持属性(->GetAttributes() 返回 E_NOTIMPL)。此外,SinkWriter 枚举并创建编码器,因此我无法访问 IMFActivate 对象。编码器实现的唯一两个接口是ICodecAPI
和IMFTransform
,看起来我无法从它们中的任何一个中获取名称。
这是真的。它并非旨在使此信息可从 IMFTransform
向后访问。很难说为什么,添加对IPersist
的支持将是一件简单而有效的事情。每当我需要进行转换时,我肯定会在那里进行转换,但是库存过滤器就这样......对开发人员不太友好。以上是关于从 SinkWriter 或 ICodecAPI 或 IMFTransform 获取编码器名称的主要内容,如果未能解决你的问题,请参考以下文章
媒体基础 SinkWriter (MP4 FastStart)
如何将音频添加到使用 SinkWriter 创建的 mp4 文件中?