2021-06-29 13:06:12 +03:00
|
|
|
#include "VideoCaptureDeviceList.h"
|
|
|
|
|
#include "Logging.h"
|
2021-07-23 16:59:22 +03:00
|
|
|
#include "MediaFoundationAPIProvider.h"
|
2021-06-29 13:06:12 +03:00
|
|
|
#include <mfapi.h>
|
|
|
|
|
#include <Mfidl.h>
|
|
|
|
|
|
|
|
|
|
#include <wil/resource.h>
|
|
|
|
|
#include <wil/com.h>
|
|
|
|
|
|
|
|
|
|
void VideoCaptureDeviceList::Clear()
|
|
|
|
|
{
|
|
|
|
|
for (UINT32 i = 0; i < m_numberDevices; i++)
|
|
|
|
|
{
|
|
|
|
|
CoTaskMemFree(m_deviceFriendlyNames[i]);
|
|
|
|
|
if (m_ppDevices[i])
|
|
|
|
|
{
|
|
|
|
|
m_ppDevices[i]->Release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CoTaskMemFree(m_ppDevices);
|
|
|
|
|
m_ppDevices = nullptr;
|
|
|
|
|
if (m_deviceFriendlyNames)
|
|
|
|
|
{
|
|
|
|
|
delete[] m_deviceFriendlyNames;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_deviceFriendlyNames = nullptr;
|
|
|
|
|
m_numberDevices = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT VideoCaptureDeviceList::EnumerateDevices()
|
|
|
|
|
{
|
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
wil::com_ptr<IMFAttributes> pAttributes;
|
|
|
|
|
Clear();
|
2021-07-23 16:59:22 +03:00
|
|
|
auto mfplatAPI = mfplatAPIProvider::create();
|
|
|
|
|
auto mfAPI = mfAPIProvider::create();
|
|
|
|
|
if (!mfplatAPI || !mfAPI)
|
|
|
|
|
{
|
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
|
}
|
2021-06-29 13:06:12 +03:00
|
|
|
|
|
|
|
|
// Initialize an attribute store. We will use this to
|
|
|
|
|
// specify the enumeration parameters.
|
|
|
|
|
|
2021-07-23 16:59:22 +03:00
|
|
|
hr = mfplatAPI->MFCreateAttributes(&pAttributes, 1);
|
2021-06-29 13:06:12 +03:00
|
|
|
|
|
|
|
|
// Ask for source type = video capture devices
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
|
{
|
|
|
|
|
hr = pAttributes->SetGUID(
|
|
|
|
|
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
|
|
|
|
|
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LOG("VideoCaptureDeviceList::EnumerateDevices(): Couldn't MFCreateAttributes");
|
|
|
|
|
}
|
|
|
|
|
// Enumerate devices.
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
|
{
|
2021-07-23 16:59:22 +03:00
|
|
|
hr = mfAPI->MFEnumDeviceSources(pAttributes.get(), &m_ppDevices, &m_numberDevices);
|
2021-06-29 13:06:12 +03:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LOG("VideoCaptureDeviceList::EnumerateDevices(): Couldn't SetGUID");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
|
{
|
|
|
|
|
LOG("VideoCaptureDeviceList::EnumerateDevices(): MFEnumDeviceSources failed");
|
|
|
|
|
return hr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_deviceFriendlyNames = new (std::nothrow) wchar_t*[m_numberDevices];
|
|
|
|
|
for (UINT32 i = 0; i < m_numberDevices; i++)
|
|
|
|
|
{
|
|
|
|
|
UINT32 nameLength = 0;
|
|
|
|
|
m_ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &m_deviceFriendlyNames[i], &nameLength);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT VideoCaptureDeviceList::GetDevice(UINT32 index, IMFActivate** ppActivate)
|
|
|
|
|
{
|
|
|
|
|
if (index >= Count())
|
|
|
|
|
{
|
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*ppActivate = m_ppDevices[index];
|
|
|
|
|
(*ppActivate)->AddRef();
|
|
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::wstring_view VideoCaptureDeviceList::GetDeviceName(UINT32 index)
|
|
|
|
|
{
|
|
|
|
|
if (index >= Count())
|
|
|
|
|
{
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m_deviceFriendlyNames[index];
|
|
|
|
|
}
|