Media Foundationでカメラデバイスを列挙する

もくじ
https://tera1707.com/entry/2022/02/06/144447

やりたいこと

先日、マイク・スピーカーのデバイスを列挙するということをやってみたが、今度はカメラを列挙したい。

で、Windowsには「Media Foundation」というのがあり、それでそういうことができるらしい。

試してみたい。

※カメラの映像を出したりもしたいが、それは時間かかりそうなのでまた今度。。。

やったこと

MSのMedia Foundationの公式を参考に、やってみた。

試したコード

コード(VSソリューション)はこちら

https://github.com/tera1707/CameraJikken

#include <windows.h>
#include <ks.h>
#include <ksproxy.h>
#include <mfapi.h>
#include <mfidl.h>
#include <string>
#include <dshow.h>

#include <combaseapi.h>

#pragma comment(lib, "Mfplat.lib")
#pragma comment(lib, "Mf.lib")

UINT32      m_cDevices;
IMFActivate** m_ppDevices;

template <class T> void SafeRelease(T** ppT)
{
    if (*ppT)
    {
        (*ppT)->Release();
        *ppT = NULL;
    }
}

void Clear()
{
    for (UINT32 i = 0; i < m_cDevices; i++)
    {
        SafeRelease(&m_ppDevices[i]);
    }
    CoTaskMemFree(m_ppDevices);
    m_ppDevices = NULL;

    m_cDevices = 0;
}

int main()
{
    HRESULT hr = S_OK;
    IMFAttributes* pAttributes = NULL;
    IMFMediaSource* pSource = NULL;

    // COMの初期化(COMのお作法)
    hr = CoInitialize(NULL);

    // 変数の初期化
    Clear();

    // メディアファンデーションの初期化みたいなもの
    hr = MFCreateAttributes(&pAttributes, 1);

    // 列挙するデバイスを「ビデオキャプチャデバイス」にする
    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetGUID(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
        );
    }

    // デバイスを列挙
    if (SUCCEEDED(hr))
    {
        hr = MFEnumDeviceSources(pAttributes, &m_ppDevices, &m_cDevices);
    }

    // 列挙したデバイスをActivate(Activateしたら操作するためのポインタが取れる)
    for (size_t i = 0; i < m_cDevices; i++)
    {
        m_ppDevices[i]->ActivateObject(__uuidof(IMFMediaSource), (void**)&pSource);
    }
    
    SafeRelease(&pAttributes);

    CoUninitialize();
}

※最後の

m_ppDevices[i]->ActivateObject(__uuidof(IMFMediaSource), (void**)&pSource);

の部分は、特に列挙するだけならいらないのだが、ここで取れたpSourceを使うと、そのカメラに対していろいろできる?らしい?ので、ここまでメモっておく。(何ができるかはまだ知らない)

備考

というのを作っては見たが、下のMS公式のMedia Foundationのサンプルを、今(2023年10月)時点のVS2022で動かしてみたら、そのまんま動かすことができたので、動きを試すなら、そっちをやってみた方がよさそう。

https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureToFile

の「MFCaptureToFile.sln」をVS2022で開いてビルドすると、そのまんま動いた。

参考になりそうなサンプル

SimpleCapture
→カメラ映像(動画)をダイアログ上に表示して流せる。

MFCaptureToFile
→カメラ映像(動画)をファイルに保存できる

参考

Media Foundation の公式

https://learn.microsoft.com/ja-jp/windows/win32/medfound/microsoft-media-foundation-sdk

microsoft/Windows-classic-samples の中にあったサンプルコード

https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureToFile/capture.cpp

https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/Win7Samples/multimedia/mediafoundation/MFCaptureToFile/capture.h