如何在 Windows 媒体基础中使用 "H.264 UVC 1.5 camera encoders"
How to use the "H.264 UVC 1.5 camera encoders" in Windows Media Foundation
我正在尝试基于 Windows Media Foundation 在 Windows 上编写一些代码,以与一些 USB UVC1.5 相机一起使用,它可以提供 H.264 流。现在我可以通过 IMFSourceReader 接口从摄像机转储 H.264 流。但是我不知道如何配置Encoder Unit的设置。
我刚刚在 Microsoft Docs 中找到一页谈论 "H.264 UVC 1.5 camera encoders"。这里是linkhttps://docs.microsoft.com/en-us/windows/win32/medfound/camera-encoder-h264-uvc-1-5。它列出了编码器的一些属性,这正是我所期望的,但它只是一个列表:(它还说明了 ICodecAPI,我还尝试使用来自 Microsoft 示例代码的以下函数来枚举 H. 264 encoder, but still not luck. (它可以枚举我PC中的所有编码器,但没有"H.264 UVC 1.5 camera encoders"相关。)
HRESULT EnumerateEncodersEx(const GUID& subtype, IMFTransform** ppEncoder)
{
HRESULT hr = S_OK;
UINT32 count = 0;
IMFActivate** ppActivate = NULL; // Array of activation objects.
MFT_REGISTER_TYPE_INFO info = { 0 };
ICodecAPI* pCodecAPI = NULL;
info.guidMajorType = MFMediaType_Video;
info.guidSubtype = subtype;
UINT32 unFlags = 0
// enumerate all three kinds of data flow
| MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
// include not-usually-included kinds of MFTs
| MFT_ENUM_FLAG_FIELDOFUSE
| MFT_ENUM_FLAG_LOCALMFT
| MFT_ENUM_FLAG_TRANSCODE_ONLY;
hr = MFTEnumEx(
MFT_CATEGORY_VIDEO_ENCODER,
unFlags,
NULL,
&info,
&ppActivate,
&count
);
if (SUCCEEDED(hr) && count == 0)
{
hr = MF_E_TOPO_CODEC_NOT_FOUND;
}
if (SUCCEEDED(hr))
{
for (UINT32 i = 0; i < count; i++)
{
WCHAR* pEncoderName;
#pragma prefast(suppress: __WARNING_PASSING_FUNCTION_UNEXPECTED_NULL, "IMFAttributes::GetAllocatedString third argument is optional");
hr = ppActivate[i]->GetAllocatedString(
MFT_FRIENDLY_NAME_Attribute,
&pEncoderName,
NULL
);
if (MF_E_ATTRIBUTENOTFOUND == hr)
{
hr = S_OK;
continue;
}
else if (FAILED(hr))
{
abort();
}
DBGMSG(L"Encoder[%d]'s Friendly Name: %s\n", i, pEncoderName);
CoTaskMemFree(pEncoderName);
}
}
if (SUCCEEDED(hr))
{
hr = ppActivate[0]->ActivateObject(IID_PPV_ARGS(ppEncoder));
}
if (SUCCEEDED(hr))
{
hr = (*ppEncoder)->QueryInterface(IID_PPV_ARGS(&pCodecAPI));
}
if (SUCCEEDED(hr))
{
SafeRelease(&pCodecAPI);
}
for (UINT32 i = 0; i < count; i++)
{
ppActivate[i]->Release();
}
CoTaskMemFree(ppActivate);
return hr;
}
看来我需要从 IMFMediaSource 获取 ICodecAPI 接口。但是不知道怎么做。
有人可以建议吗?预先感谢您的帮助。
我自己查不到,如果你用IMFSourceReader成功了,试试看吧:
- 使用 MF_SOURCE_READER_FIRST_VIDEO_STREAM 调用 IMFSourceReader::GetServiceForStream 以获取 IMFTransform :GetServiceForStream
- 比像您一样使用 IMFTransform 的 ICodecAPI 的 QueryInterface。
PS :也许您需要在设置 MediaType 之前或之后执行此操作。
我找到解决办法了。 ICodecAPI接口可以直接从IMFMediaSource获取。
IMFMediaSource* ppSource = NULL;
CreateVideoDeviceSource(&ppSource);
HRESULT hr;
IMFSourceReader* pReader;
hr = EnumerateCaptureFormats(ppSource); // This can show the formats the camera support.
if (FAILED(hr))
abort();
hr = MFCreateSourceReaderFromMediaSource(ppSource, NULL, &pReader);
if (FAILED(hr))
abort();
ICodecAPI* pCodecApi = NULL;
hr = ppSource->QueryInterface(IID_PPV_ARGS(&pCodecApi));
if (FAILED(hr))
abort();
我可以通过这个 ICodecAPI 接口更改 UVC1.5 的 H264 编码器设置。
我正在尝试基于 Windows Media Foundation 在 Windows 上编写一些代码,以与一些 USB UVC1.5 相机一起使用,它可以提供 H.264 流。现在我可以通过 IMFSourceReader 接口从摄像机转储 H.264 流。但是我不知道如何配置Encoder Unit的设置。
我刚刚在 Microsoft Docs 中找到一页谈论 "H.264 UVC 1.5 camera encoders"。这里是linkhttps://docs.microsoft.com/en-us/windows/win32/medfound/camera-encoder-h264-uvc-1-5。它列出了编码器的一些属性,这正是我所期望的,但它只是一个列表:(它还说明了 ICodecAPI,我还尝试使用来自 Microsoft 示例代码的以下函数来枚举 H. 264 encoder, but still not luck. (它可以枚举我PC中的所有编码器,但没有"H.264 UVC 1.5 camera encoders"相关。)
HRESULT EnumerateEncodersEx(const GUID& subtype, IMFTransform** ppEncoder)
{
HRESULT hr = S_OK;
UINT32 count = 0;
IMFActivate** ppActivate = NULL; // Array of activation objects.
MFT_REGISTER_TYPE_INFO info = { 0 };
ICodecAPI* pCodecAPI = NULL;
info.guidMajorType = MFMediaType_Video;
info.guidSubtype = subtype;
UINT32 unFlags = 0
// enumerate all three kinds of data flow
| MFT_ENUM_FLAG_SYNCMFT
| MFT_ENUM_FLAG_ASYNCMFT
| MFT_ENUM_FLAG_HARDWARE
// include not-usually-included kinds of MFTs
| MFT_ENUM_FLAG_FIELDOFUSE
| MFT_ENUM_FLAG_LOCALMFT
| MFT_ENUM_FLAG_TRANSCODE_ONLY;
hr = MFTEnumEx(
MFT_CATEGORY_VIDEO_ENCODER,
unFlags,
NULL,
&info,
&ppActivate,
&count
);
if (SUCCEEDED(hr) && count == 0)
{
hr = MF_E_TOPO_CODEC_NOT_FOUND;
}
if (SUCCEEDED(hr))
{
for (UINT32 i = 0; i < count; i++)
{
WCHAR* pEncoderName;
#pragma prefast(suppress: __WARNING_PASSING_FUNCTION_UNEXPECTED_NULL, "IMFAttributes::GetAllocatedString third argument is optional");
hr = ppActivate[i]->GetAllocatedString(
MFT_FRIENDLY_NAME_Attribute,
&pEncoderName,
NULL
);
if (MF_E_ATTRIBUTENOTFOUND == hr)
{
hr = S_OK;
continue;
}
else if (FAILED(hr))
{
abort();
}
DBGMSG(L"Encoder[%d]'s Friendly Name: %s\n", i, pEncoderName);
CoTaskMemFree(pEncoderName);
}
}
if (SUCCEEDED(hr))
{
hr = ppActivate[0]->ActivateObject(IID_PPV_ARGS(ppEncoder));
}
if (SUCCEEDED(hr))
{
hr = (*ppEncoder)->QueryInterface(IID_PPV_ARGS(&pCodecAPI));
}
if (SUCCEEDED(hr))
{
SafeRelease(&pCodecAPI);
}
for (UINT32 i = 0; i < count; i++)
{
ppActivate[i]->Release();
}
CoTaskMemFree(ppActivate);
return hr;
}
看来我需要从 IMFMediaSource 获取 ICodecAPI 接口。但是不知道怎么做。
有人可以建议吗?预先感谢您的帮助。
我自己查不到,如果你用IMFSourceReader成功了,试试看吧:
- 使用 MF_SOURCE_READER_FIRST_VIDEO_STREAM 调用 IMFSourceReader::GetServiceForStream 以获取 IMFTransform :GetServiceForStream
- 比像您一样使用 IMFTransform 的 ICodecAPI 的 QueryInterface。
PS :也许您需要在设置 MediaType 之前或之后执行此操作。
我找到解决办法了。 ICodecAPI接口可以直接从IMFMediaSource获取。
IMFMediaSource* ppSource = NULL;
CreateVideoDeviceSource(&ppSource);
HRESULT hr;
IMFSourceReader* pReader;
hr = EnumerateCaptureFormats(ppSource); // This can show the formats the camera support.
if (FAILED(hr))
abort();
hr = MFCreateSourceReaderFromMediaSource(ppSource, NULL, &pReader);
if (FAILED(hr))
abort();
ICodecAPI* pCodecApi = NULL;
hr = ppSource->QueryInterface(IID_PPV_ARGS(&pCodecApi));
if (FAILED(hr))
abort();
我可以通过这个 ICodecAPI 接口更改 UVC1.5 的 H264 编码器设置。