Microsoft Media Foundation은 오디오 및 비디오 캡처를 지원합니다. 비디오 캡처 디바이스는 UVC 클래스 드라이버를 통해 지원되며 UVC 1.1과 호환되어야 합니다. 오디오 캡처 디바이스는 WASAPI(Windows Audio Session API)를 통해 지원됩니다.
캡처 디바이스는 미디어 원본 개체에 의해 Media Foundation에 표시되며, 이 개체는 IMFMediaSource 인터페이스를 노출합니다. 대부분의 경우 애플리케이션은 이 인터페이스를 직접 사용하지 않지만 원본 판독기 같은 상위 수준 API를 사용하여 캡처 디바이스를 제어합니다.
캡처 디바이스 열거
시스템에서 캡처 디바이스를 열거하려면 다음 단계를 수행합니다.
MFCreateAttributes 함수를 호출하여 특성 저장소를 만듭니다.
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE 특성을 다음 값 중 하나로 설정합니다.
값 묘사 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID 오디오 캡처 디바이스를 열거합니다. MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID 비디오 캡처 디바이스를 열거합니다. MFEnumDeviceSources 함수를 호출합니다. 이 함수는 IMFActivate 포인터 배열을 할당합니다. 각 포인터는 시스템의 한 디바이스에 대한 활성화 개체를 나타냅니다.
IMFActivate::ActivateObject 메서드를 호출하여 활성화 개체 중 하나에서 미디어 원본의 인스턴스를 만듭니다.
다음 예제에서는 열거형 목록에서 첫 번째 비디오 캡처 디바이스에 대한 미디어 원본을 만듭니다.
HRESULT CreateVideoCaptureDevice(IMFMediaSource **ppSource)
{
*ppSource = NULL;
UINT32 count = 0;
IMFAttributes *pConfig = NULL;
IMFActivate **ppDevices = NULL;
// Create an attribute store to hold the search criteria.
HRESULT hr = MFCreateAttributes(&pConfig, 1);
// Request video capture devices.
if (SUCCEEDED(hr))
{
hr = pConfig->SetGUID(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
);
}
// Enumerate the devices,
if (SUCCEEDED(hr))
{
hr = MFEnumDeviceSources(pConfig, &ppDevices, &count);
}
// Create a media source for the first device in the list.
if (SUCCEEDED(hr))
{
if (count > 0)
{
hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(ppSource));
}
else
{
hr = MF_E_NOT_FOUND;
}
}
for (DWORD i = 0; i < count; i++)
{
ppDevices[i]->Release();
}
CoTaskMemFree(ppDevices);
return hr;
}
다음을 포함하여 다양한 특성에 대한 활성화 개체를 쿼리할 수 있습니다.
- MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME 특성에는 디바이스의 표시 이름이 포함됩니다. 표시 이름은 사용자에게 표시하기에 적합하지만 고유하지 않을 수 있습니다.
- 비디오 디바이스의 경우 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 특성에는 디바이스에 대한 기호 링크가 포함됩니다. 기호 링크는 시스템의 디바이스를 고유하게 식별하지만 읽을 수 있는 문자열은 아닙니다.
- 오디오 디바이스의 경우 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID 특성에는 디바이스의 오디오 엔드포인트 ID가 포함됩니다. 오디오 엔드포인트 ID는 기호 링크와 유사합니다. 시스템에서 디바이스를 고유하게 식별하지만 읽을 수 있는 문자열은 아닙니다.
다음 예제에서는 IMFActivate 포인터의 배열을 가져와서 각 디바이스의 표시 이름을 디버그 창에 출력합니다.
void DebugShowDeviceNames(IMFActivate **ppDevices, UINT count)
{
for (DWORD i = 0; i < count; i++)
{
HRESULT hr = S_OK;
WCHAR *szFriendlyName = NULL;
// Try to get the display name.
UINT32 cchName;
hr = ppDevices[i]->GetAllocatedString(
MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
&szFriendlyName, &cchName);
if (SUCCEEDED(hr))
{
OutputDebugString(szFriendlyName);
OutputDebugString(L"\n");
}
CoTaskMemFree(szFriendlyName);
}
}
비디오 디바이스에 대한 기호 링크를 이미 알고 있는 경우 디바이스에 대한 미디어 원본을 만드는 또 다른 방법이 있습니다.
- MFCreateAttributes 호출하여 특성 저장소를 만듭니다.
- MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE 특성을 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID설정합니다.
- MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 특성을 기호 링크로 설정합니다.
- MFCreateDeviceSource 또는 MFCreateDeviceSourceActivate함수를호출합니다. 전자는 IMFMediaSource 포인터를 반환합니다. 후자는 활성화 개체에 대한 IMFActivate 포인터를 반환합니다. 활성화 개체를 사용하여 원본을 만들 수 있습니다. (활성화 개체를 다른 프로세스로 마샬링할 수 있으므로 다른 프로세스에서 원본을 만들려는 경우에 유용합니다. 자세한 내용은 활성화 개체.)를 참조하세요.
다음 예제에서는 비디오 디바이스의 기호 링크를 가져와 미디어 원본을 만듭니다.
HRESULT CreateVideoCaptureDevice(PCWSTR *pszSymbolicLink, IMFMediaSource **ppSource)
{
*ppSource = NULL;
IMFAttributes *pAttributes = NULL;
IMFMediaSource *pSource = NULL;
HRESULT hr = MFCreateAttributes(&pAttributes, 2);
// Set the device type to video.
if (SUCCEEDED(hr))
{
hr = pAttributes->SetGUID(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
);
}
// Set the symbolic link.
if (SUCCEEDED(hr))
{
hr = pAttributes->SetString(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
(LPCWSTR)pszSymbolicLink
);
}
if (SUCCEEDED(hr))
{
hr = MFCreateDeviceSource(pAttributes, ppSource);
}
SafeRelease(&pAttributes);
return hr;
}
오디오 엔드포인트 ID에서 오디오 디바이스를 만드는 동일한 방법이 있습니다.
- MFCreateAttributes 호출하여 특성 저장소를 만듭니다.
- MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE 특성을 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID설정합니다.
- MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID 특성을 엔드포인트 ID로 설정합니다.
- MFCreateDeviceSource 또는 MFCreateDeviceSourceActivate함수를호출합니다.
다음 예제에서는 오디오 엔드포인트 ID를 사용하고 미디어 원본을 만듭니다.
HRESULT CreateAudioCaptureDevice(PCWSTR *pszEndPointID, IMFMediaSource **ppSource)
{
*ppSource = NULL;
IMFAttributes *pAttributes = NULL;
IMFMediaSource *pSource = NULL;
HRESULT hr = MFCreateAttributes(&pAttributes, 2);
// Set the device type to audio.
if (SUCCEEDED(hr))
{
hr = pAttributes->SetGUID(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID
);
}
// Set the endpoint ID.
if (SUCCEEDED(hr))
{
hr = pAttributes->SetString(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID,
(LPCWSTR)pszEndPointID
);
}
if (SUCCEEDED(hr))
{
hr = MFCreateDeviceSource(pAttributes, ppSource);
}
SafeRelease(&pAttributes);
return hr;
}
캡처 디바이스 사용
캡처 디바이스에 대한 미디어 원본을 만든 후 원본 판독기 사용하여 디바이스에서 데이터를 가져옵니다. 원본 판독기는 캡처 오디오 데이터 또는 비디오 프레임을 포함하는 미디어 샘플을 제공합니다. 다음 단계는 애플리케이션 시나리오에 따라 달라집니다.
- 비디오 미리 보기: Microsoft Direct3D 또는 Direct2D를 사용하여 비디오를 표시합니다.
- 파일 캡처: 싱크 기록기 사용하여 파일을 인코딩합니다.
- 오디오 미리 보기: WASAPI사용합니다.
오디오 캡처를 비디오 캡처와 결합하려면 집계 미디어 원본사용합니다. 집계 미디어 원본은 미디어 원본 컬렉션을 포함하고 모든 스트림을 단일 미디어 원본 개체로 결합합니다. 집계 미디어 원본의 인스턴스를 만들려면 MFCreateAggregateSource 함수를 호출합니다.
캡처 디바이스 종료
캡처 디바이스가 더 이상 필요하지 않은 경우 MFCreateDeviceSource 호출하거나 IMFActivate::ActivateObject호출하여 가져온 IMFMediaSource 개체에서 Shutdown 호출하여 디바이스를 종료해야 합니다. Shutdown 호출될 때까지 시스템에서 IMFMediaSource 리소스에 대한 참조를 유지할 수 있으므로 종료 호출하지 않으면 메모리 누수 발생이 발생할 수 있습니다.
if (g_pSource)
{
g_pSource->Shutdown();
g_pSource->Release();
g_pSource = NULL;
}
캡처 디바이스에 대한 기호 링크가 포함된 문자열을 할당한 경우 이 개체도 해제해야 합니다.
CoTaskMemFree(g_pwszSymbolicLink);
g_pwszSymbolicLink = NULL;
g_cchSymbolicLink = 0;
관련 항목