目的
現在接続されていビデオキャプチャデバイスをプログラムから取得します。
ビデオキャプチャデバイスを扱うライブラリとしては DirectShow が有名だと思いますが、2016年現在でサポート期間中である WindowsVista 以降では Media Foundation が後継となっていますので、Media Foundation を使用します。
サンプルコード
必要ライブラリ
- mfplat.lib
- Mf.lib
sample.cpp
# include <cstdint>
# include <iostream>
# include <vector>
# include <string>
# include <memory>
# include <mfapi.h>
# include <mfidl.h>
HRESULT GetVideoDeviceNames(std::vector<std::wstring>& deviceNames)
{
HRESULT hr;
std::shared_ptr<IMFAttributes> pAttributes;
{
IMFAttributes *prawAttributes = nullptr;
hr = MFCreateAttributes(&prawAttributes, 1);
if (FAILED(hr))
return hr;
pAttributes = std::shared_ptr<IMFAttributes>(prawAttributes, [](auto* p) { p->Release(); });
}
hr = pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
if (FAILED(hr))
return hr;
IMFActivate** pprawDevice = nullptr;
uint32_t count(0);
hr = MFEnumDeviceSources(pAttributes.get(), &pprawDevice, &count);
if (FAILED(hr))
return hr;
deviceNames.resize(count);
for (int i(0); i < count; ++i)
{
wchar_t* buffer;
uint32_t length;
hr = pprawDevice[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &buffer, &length);
if (FAILED(hr))
return hr;
deviceNames[i] = buffer;
}
if (pprawDevice != nullptr)
{
for (int i(0); i < count; ++i)
pprawDevice[i]->Release();
CoTaskMemFree(pprawDevice);
}
return S_OK;
}
int main(int argc, char* argv[])
{
HRESULT hr;
hr = MFStartup(MF_VERSION);
if (FAILED(hr))
return hr;
std::vector<std::wstring> deviceNames;
hr = GetVideoDeviceNames(deviceNames);
if (FAILED(hr))
return hr;
for (const auto& wstr : deviceNames)
std::wcout << wstr << std::endl;
hr = MFShutdown();
if (FAILED(hr))
return hr;
std::wcout << std::endl;
std::wcout << L"Press any key to exit..." << std::endl;
std::wcin.get();
return 0;
}
結果
Surface Pro で試した結果を載せます
Front LifeCam
Rear LifeCam
Press any key to exit...