Skip to content

Instantly share code, notes, and snippets.

@aramg
Created June 26, 2024 18:43
Show Gist options
  • Save aramg/82a95f81c43aa8e3a3d269120726ddaf to your computer and use it in GitHub Desktop.
Save aramg/82a95f81c43aa8e3a3d269120726ddaf to your computer and use it in GitHub Desktop.
MediaFoundation Test
#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <mfidl.h>
#include <mfapi.h>
#include <mfreadwrite.h>
#include <objbase.h>
#include <windows.h>
#pragma comment(lib,"Mf.lib")
#pragma comment(lib,"Mfplat.lib")
#pragma comment(lib,"Mfreadwrite.lib")
#pragma comment(lib,"mfuuid.lib")
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"shlwapi.lib")
template <class T> void SAFE_RELEASE(T** ppT)
{
if (*ppT)
{
(*ppT)->Release();
*ppT = NULL;
}
}
template <class T> inline void SAFE_RELEASE(T*& pT)
{
if (pT != NULL)
{
pT->Release();
pT = NULL;
}
}
int main(void) {
HRESULT hr = S_OK;
#define CHECK_HR(hr, msg) if (hr != S_OK) { fprintf(stderr, msg); fprintf(stderr, " Error: %.2X.\n", hr); goto done; }
CHECK_HR(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE), "COM initialisation failed.");
CHECK_HR(MFStartup(MF_VERSION), "Media Foundation initialisation failed.");
IMFAttributes *videoConfig = NULL;
CHECK_HR(MFCreateAttributes(&videoConfig, 1), "Error creating video configuration.");
hr = videoConfig->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
CHECK_HR(hr, "Error initialising video configuration object.");
// Enum devices
UINT32 droidcamIndex = -1;
UINT32 videoDeviceCount = 0;
IMFActivate **ppDevices = NULL;
CHECK_HR(MFEnumDeviceSources(videoConfig, &ppDevices, &videoDeviceCount), "Error enumerating video devices.");
for (UINT32 i = 0; i < videoDeviceCount; i++) {
WCHAR *szFriendlyName = NULL;
hr = ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &szFriendlyName, NULL);
if (SUCCEEDED(hr)) {
wprintf(L"Device[%d]: %s\n", i, szFriendlyName);
if (wcsstr(szFriendlyName, L"DroidCam")) {
droidcamIndex = i;
}
}
else {
fprintf(stderr, "error getting friendly name @%d\n", i);;
}
CoTaskMemFree(szFriendlyName);
}
IMFMediaSource *pVideoSource = NULL;
IMFSourceReader *pVideoReader = NULL;
if (droidcamIndex >= 0) {
printf("trying to activate device %d\n", droidcamIndex);
IMFActivate* pActivate = ppDevices[droidcamIndex];
CHECK_HR(pActivate->ActivateObject(IID_PPV_ARGS(&pVideoSource)),
"Error activating video device.");
// Create a source reader.
CHECK_HR(MFCreateSourceReaderFromMediaSource(pVideoSource, videoConfig, &pVideoReader),
"Error creating video source reader.");
DWORD dwMediaTypeIndex = 0;
while (SUCCEEDED(hr))
{
IMFMediaType *mediaType = NULL;
hr = pVideoReader->GetNativeMediaType(MF_SOURCE_READER_FIRST_VIDEO_STREAM, dwMediaTypeIndex++, &mediaType);
if (SUCCEEDED(hr)) {
// Get width and height
UINT32 width, height;
MFGetAttributeSize(mediaType, MF_MT_FRAME_SIZE, &width, &height);
printf("found size: %dx%d\n", width, height);
mediaType->Release();
}
else {
break;
}
}
} // droidcamIndex
done:
printf("done\n");
SAFE_RELEASE(pVideoReader);
SAFE_RELEASE(pVideoSource);
SAFE_RELEASE(ppDevices);
SAFE_RELEASE(videoConfig);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment