UWP デバイス アプリのカメラ ドライバー MFT の作成

重要

このトピックは非推奨になりました。 更新されたガイダンスについては、デバイス MFT 設計ガイドを参照してください。

UWP デバイス アプリは、デバイスの製造元が、カメラ ドライバー MFT (メディア ファンデーション変換) を使用して、カメラのビデオ ストリームにカスタム設定と特殊効果を適用できるようにします。 このトピックでは、ドライバー MFT の概要、およびドライバー MFT サンプルを使用して作成する方法について説明します。 UWP デバイス アプリ全般の詳細については、「UWP デバイス アプリの概要」を参照してください。

ドライバー MFT。

このセクションでは、カメラから送られるメディア キャプチャ ストリームに効果を適用するために作成するメディア ファンデーション変換(MFT) について説明します。 これは、カラー エフェクト、スキーム モード、顔追跡エフェクトなどのトランスフォームを提供して、実際に他のカメラとの差別化を図る方法です。 ドライバー MFT と呼ばれるこの MFT は、UWP アプリがビデオ キャプチャを開始すると、カメラ ドライバーから送られる接続されたビデオ ストリームに最初に適用されます。 そのアプリがカメラ オプション UI を呼び出すと、Windows は、カスタム エフェクトを制御するためにドライバ MFT が実装されているすべてのインターフェイスへのアクセスを自動的に提供します。

the camera driver mft helps a windows store device app provide custom effects.

UWP デバイス アプリには、ドライバー MFT は必要ありません。 デバイスの製造元は、ハードウェアのブランディングを含む差別化されたユーザー インターフェイスを提供するだけで、ビデオ ストリームにカスタム設定や特殊効果を適用せず、ドライバー MFT なしで UWP デバイス アプリを実装することを選択できます。

ドライバー MFT の活用方法

カメラ用の UWP デバイス アプリは、CameraCaptureUI API から呼び出す Microsoft Store アプリとは異なるプロセスで実行されます。 Microsoft Store デバイス アプリでドライバー MFT を制御するには、異なる処理領域で特定のイベント シーケンスを発生させる必要があります。

  1. UWP アプリは写真をキャプチャする必要があるため、CaptureFileAsync メソッドを呼び出します

  2. Windows は、ドライバー MFT ポインターとカメラのデバイス ID を要求します。

  3. ドライバー MFT ポインターが設定ホストに渡されます

  4. ホストは、カメラに関連付けられている Microsoft Store デバイス アプリのアプリ ID のデバイス プロパティにクエリを実行します (デバイス メタデータごと)

  5. UWP デバイス アプリが見つからない場合、既定のポップアップがキャプチャ エンジンとやりとりします

  6. UWP デバイス アプリが見つかると、アプリはアクティブ化され、設定ホストがドライバー MFT ポインターをアプリに渡します

  7. UWP デバイス アプリは、ポインターを介して公開されるインターフェイスを使用してドライバー MFT を制御します

the process interaction for invoking a windows store device app.

AvStream ドライバー モデルの要件

カメラのドライバーでは AvStream ドライバー モデルを使用する必要があります。 AVStream ドライバー モデルの詳細については、「AVStream ミニドライバー設計ガイド」を参照してください。

ドライバー MFT をアプリに公開する方法

ドライバー MFT は、COM インターフェースとして Windows に登録されるため、そこで実装される変換を、カメラなどの特定のデバイスから送られるメディア ストリームに適用できます。

Note

ドライバー MFT はデバイス固有のものであり、汎用 MFT ではないため、MFTRegister 関数を使用して登録しないでください。 レジストリ キーについては、このトピックで後述する「ドライバー MFTのインストールと登録」セクションを参照してください。

アプリがビデオ キャプチャを開始すると、メディア ファンデーション ソース リーダーがインスタンス化され、ビデオ ストリームが提供されます。 このメディア ソースは、デバイス レジストリ キーからレジストリ値を読み取ります。 ドライバー MFT の COM クラスの CLSID がレジストリ値で見つかると、ソース リーダーはドライバー MFT をインスタンス化してメディア パイプラインに挿入します。

関連付けられているデバイスがビデオをキャプチャするために使用されている場合は、UWP デバイス アプリに加えて、このドライバー MFT 機能にも、次の API を使用してアクセスできます。

  • HTML を使用した UWP アプリ内の HTML5 <video> タグ。 ドライバー MFT が有効になっている変換は、次のコード例のように、<video> 要素を使用して再生中のビデオ に影響します。

    var video = document.getElementById('myvideo');
        video.src = URL.createObjectURL(fileItem);
        video.play();
    
  • Windows ランタイムを使用する UWP アプリの Windows.Media.MediaCapture API。 この API の使用方法の詳細については、メディア キャプチャのサンプルを参照してください。

  • メディア データを処理するアプリ用のメディア ファンデーションのソース リーダー。 ドライバー MFT は、IMFSourceReaderEx::GetTransformForStream の呼び出し時に最初 (0 番目) の MFT としてアプリケーションに公開されます。 返されるカテゴリは MFT_CATEGORY_VIDEO_EFFECT です。

    source reader's role in media capture.

マルチピン カメラ

3 ピンまたは他のマルチピン カメラがある場合は、「マルチピン カメラのドライバー MFT に関する考慮事項」を参照してください。

ドライバー MFT の実装

このセクションでは、ドライバー MFT の実装について説明します。 UWP デバイス アプリと連携するドライバー MFT の完全な例については、ドライバー MFT のサンプルを参照してください。

開発ツール

Microsoft Visual Studio Professional または Microsoft Visual Studio Ultimate が必要です。

ドライバー MFT の特性

ドライバー MFT はストリームごとにインスタンス化されます。 カメラがサポートするストリームごとに、MFT のインスタンスがインスタンス化されて接続されます。 ドライバー MFT には、1 つの入力ストリームと 1 つの出力ストリームがあるものと想定されています。 ドライバー MFT は、同期 MFT または非同期 MFT のどちらでもかまいません。

カメラとドライバー MFT の間の通信

メディア ソースとドライバー MFT 間の双方向通信を有効にするため、ソース ストリームの属性ストアへのポインターは、ドライバー MFT の入力ストリーム属性ストアで MFT_CONNECTED_STREAM_ATTRIBUTE として設定されます。 これは、次の例のように、ドライバー MFT で MFT_ENUM_HARDWARE_URL_Attribute を公開することで有効になるハンドシェイク プロセスを通じて発生します。

HRESULT CDriverMft::GetAttributes(IMFAttributes** ppAttributes)
{
    HRESULT hr = S_OK;
    if (NULL == ppAttributes)
    {
       return E_POINTER; 
    };
        if(!m_pGlobalAttributes) {
           MFCreateAttributes(&m_pGlobalAttributes, 1);
           m_pGlobalAttributes-> 
             SetString(MFT_ENUM_HARDWARE_URL_Attribute, L"driverMFT");
        }
        *ppAttributes = m_pGlobalAttributes;
        (*ppAttributes)->AddRef();
        return S_OK;
}

この例では、ドライバー MFT の属性ストア内の MFT_CONNECTED_STREAM_ATTRIBUTE は、デバイス ソースのストリームの属性ストアを指すように設定されています。 カメラと MFT 間の通信を設定する方法の詳細については、「ハードウェア ハンドシェイク シーケンス」を参照してください。

デバイス ソース情報にアクセスする方法

次のコード例は、ドライバー MFT で入力属性ストアからソース変換へのポインターを取得する方法を示しています。 その後、ドライバー MFT はソース ポインターを使用して、デバイスのソース情報を取得できます。

if(!m_pSourceTransform && m_pInputAttributes) {

          m_pInputAttributes->
              GetUnknown( MFT_CONNECTED_STREAM_ATTRIBUTE,
              IID_PPV_ARGS(&pSourceAttributes));
          pSourceAttributes-> 
              GetUnknown(
              MF_DEVICESTREAM_EXTENSION_PLUGIN_CONNECTION_POINT,            
              IID_PPV_ARGS(&pUnk)));
          pUnk->QueryInterface(__uuidof(IMFTransform), 
              (void**)&m_pSourceTransform));
      }
      if (m_pSourceTransform) {
         // Put code to get device source information here.         
      }

パススルー モードを実装する方法

ドライバー MFT をパススルー モードにするには、入力ストリームと出力ストリームに同じメディアの種類を指定します。 MFT では引き続き、ProcessInputProcessOutput の呼び出しが行われます。 パススルー モードで処理を行うかどうかの判断は、ドライバーの MFT 実装に委ねられます。

含めるヘッダー ファイル

ドライバー MFT で実装する必要がある IInspectableIMFTransform のメソッドでは、ヘッダー ファイルを含める必要があります。 含めるべきヘッダー ファイルの一覧については、カメラ用 UWP デバイス アプリのサンプルの SampleMFT0 ディレクトリにある stdafx.h を参照してください。

// required for IInspectable
#include <inspectable.h>

IInspectable を実装する方法

カメラの UWP デバイス アプリから使用することを意図としたドライバー MFT では、IInspectable のメソッドを実装して、起動時に Microsoft Store デバイス アプリがドライバー MFT へのポインターにアクセスできるようにする必要があります。 ドライバー MFT では、次のように IInspectable のメソッドを実装する必要があります。

  • IInspectable::GetIidsiids out パラメーターで null を返し、iidCount out パラメーターで 0 を返す必要があります。

  • IInspectable::GetRuntimeClassName は out パラメーターで null を返す必要があります。

  • IInspectable::GetRuntiGetTrustLevel は out パラメーターで TrustLevel::BaseTrust を返す必要があります。

次のコード例は、サンプル ドライバー MFT で IInspectable メソッドを実装する方法を示しています。 このコードは、サンプルの SampleMFT0 にある Mft0.cpp ファイルにあります。

// Mft0.cpp
STDMETHODIMP CMft0::GetIids( 
    /* [out] */ __RPC__out ULONG *iidCount,
    /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID **iids)
{
    HRESULT hr = S_OK;
    do {
        CHK_NULL_PTR_BRK(iidCount);
        CHK_NULL_PTR_BRK(iids);
        *iids = NULL;
        *iidCount = 0;
    } while (FALSE);

    return hr;
}

STDMETHODIMP CMft0::GetRuntimeClassName( 
    /* [out] */ __RPC__deref_out_opt HSTRING *className)
{
    HRESULT hr = S_OK;
    do {
        CHK_NULL_PTR_BRK(className);
        *className = NULL;
    } while (FALSE);

    return hr;
}

STDMETHODIMP CMft0::GetTrustLevel( 
    /* [out] */ __RPC__out TrustLevel *trustLevel)
{
    HRESULT hr = S_OK;
    do {
        CHK_NULL_PTR_BRK(trustLevel);
        *trustLevel = TrustLevel::BaseTrust;
    } while (FALSE);

    return hr;
}

COM の実装

カメラの UWP デバイス アプリに正しくマーシャリングするためには、ドライバー MFT で実装するインターフェイスごとに IUnknown を実装し、そこから派生させる必要があります。 これを示すドライバー MFT の .idl ファイルの例を次に示します。

// SampleMft0.idl : IDL source for SampleMft0
//

// This file will be processed by the MIDL tool to
// produce the type library (SampleMft0.tlb) and marshalling code.

import "oaidl.idl";
import "ocidl.idl";
import "Inspectable.idl";
import "mftransform.idl";
[
    object,
    uuid(F5208B72-A37A-457E-A309-AE3060780E21),
    oleautomation,
    nonextensible,
    pointer_default(unique)
]
interface IMft0 : IUnknown{
    [id(1)] HRESULT UpdateDsp([in] UINT32 uiPercentOfScreen);
    [id(2)] HRESULT Enable(void);
    [id(3)] HRESULT Disable(void);
    [id(4)] HRESULT GetDspSetting([out] UINT* puiPercentOfScreen, [out] BOOL* pIsEnabled);
};
[
    uuid(DE05674A-C564-4C0E-9B7C-E1519F7AA767),
    version(1.0),
]
library SampleMft0Lib
{
    importlib("stdole2.tlb");
    [
        uuid(7BB640D9-33A4-4759-B290-F41A31DCF848)      
    ]
    coclass Mft0
    {
        [default] interface IMft0;
        interface IInspectable;
        interface IMFTransform;
    };
};

Note

ドライバー MFT は、CoCreateInstance を使用して作成できる標準の COM クラスです。 汎用の MFT ではないため、MFTRegister 関数を使用して登録しないでください。

プロキシの作成

ドライバー MFT はアウトプロセス サーバーです。 UWP デバイス アプリで使用するには、プロキシでマーシャリング サポートを提供して、ドライバー MFT インターフェイスをプロセス境界を越えて使用できるようにする必要があります。 ドライバー MFT のサンプルで、この例を確認できます。 サンプルでは、MIDL コンパイラを使用してスタブレス プロキシを生成します。

ドライバー MFT のアプリへの公開

ドライバー MFT と対話する C# または JavaScript で UWP デバイス アプリを作成するには、Microsoft Store デバイス アプリの Microsoft Visual Studio プロジェクトで追加コンポーネントを作成する必要があります。 このコンポーネントは、Microsoft Store デバイス アプリに表示される Windows ランタイム コンポーネントでドライバー MFT インターフェイスを公開するラッパーです。

カメラ用 UWP デバイス アプリのサンプルのラッパー サブプロジェクトでは、ドライバー MFT を Windows ランタイム に公開して、C# または JavaScript に実装されている UWP デバイス アプリから使用できるようにする方法の例を確認できます。 これは、ドライバー MFT のサンプルと連携するように設計されています。 サンプルのインストール、実行、テストに関する詳細なガイドについては、ドライバー MFT サンプル ページを参照してください。

ドライバー MFT のインストールと登録

このセクションでは、ドライバー MFT をインストールする手順について説明します。

  1. ドライバー MFT DLL を、次の場所のサブディレクトリにインストールする必要があります。

    • %SystemDrive%\Program Files\
  2. カメラ インストーラーはドライバー MFT を登録する際、ドライバー MFT DLL で regsvr32 を呼び出すか、インストーラーが登録に使用する DLL のドライバー マニフェスト (.man) ファイルを提供します。

  3. カメラのレジストリ キーに CameraPostProcessingPluginCLSID 値を設定します。 INF ファイルで、ドライバー MFT クラスの CLSID GUID に CameraPostProcessingPluginCLSID 値を設定して、デバイスのデバイス クラス レジストリ キーにドライバー MFT の CLSID を指定する必要があります。 カメラのレジストリ キーを事前設定する INF ファイル エントリの例を次に示します。

KSCATEGORY_VIDEO_CAMERA:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\{E5323777-F976-4f5b-9B55-B94699C46E44}\##?#USB#VID_045E&PID_075D&MI_00#8&23C3DB65&0&0000#{E5323777-F976-4f5b-9B55-B94699C46E44}\#GLOBAL\Device Parameters]
"CLSID"="{17CCA71B-ECD7-11D0-B908-00A0C9223196}"
"FriendlyName"="USB Video Device"
"RTCFlags"=dword:00000010
"CameraPostProcessingPluginCLSID"="{3456A71B-ECD7-11D0-B908-00A0C9223196}" 
KSCATEGORY_CAPTURE:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\{ 65E8773D-8F56-11D0-A3B9-00A0C9223196}\##?#USB#VID_045E&PID_075D&MI_00#8&23C3DB65&0&0000#{65E8773D-8F56-11D0-A3B9-00A0C9223196}\#GLOBAL\Device Parameters]
"CLSID"="{17CCA71B-ECD7-11D0-B908-00A0C9223196}"
"FriendlyName"="USB Video Device"
"RTCFlags"=dword:00000010
"CameraPostProcessingPluginCLSID"="{3456A71B-ECD7-11D0-B908-00A0C9223196}"

Note

カメラには KSCATEGORY_VIDEO_CAMERA をお勧めします。 デバイスの登録方法にもよりますが、通常、必要なレジストリ キーは 1 つのみです。

アプリをカメラに関連付ける

このセクションでは、デバイス メタデータと Windows レジストリでカメラを識別するために必要な手順について説明します。 このメタデータにより UWP デバイス アプリをペアリングし、アプリを識別できるため、カメラを初めて接続したときにシームレスにダウンロードできます。

更新プログラム

アプリの初回インストール後に、ユーザーがアプリの更新バージョンをダウンロードすると、更新プログラムがカメラ キャプチャ エクスペリエンスに統合されます。 ただし、更新プログラムは自動的にはダウンロードされません。 アプリが自動的にインストールされるのは初回接続時のみのため、ユーザーは Microsoft Store から追加のアプリ更新プログラムをダウンロードする必要があります。 UWP デバイス アプリのメイン ページでは、更新プログラムが利用可能であることを通知したり、更新プログラムをダウンロードするためのリンクを提供したりできます。

重要

更新されたアプリは、Windows Update を通じて配布される更新されたドライバーで動作するはずです。

複数のカメラ

デバイス メタデータで同じ UWP デバイス アプリを複数のカメラ モデルで宣言できます。 システムに複数の内部埋め込みカメラがある場合、カメラは同じ UWP デバイス アプリを共有する必要があります。 アプリには使用中のカメラを判断するためのロジックが含まれており、その他のオプション エクスペリエンスでカメラごとに異なる UI を表示できます。 そのエクスペリエンスのカスタマイズ方法については、「カメラ オプションをカスタマイズする方法」を参照してください。

内部カメラ

内部カメラ用 UWP デバイス アプリは、Microsoft Store から自動インストールできますが、最もシームレスなユーザー エクスペリエンスを実現するにはプレインストールすることをお勧めします。 内部カメラをサポートし、UWP デバイス アプリを関連付けるには、追加の手順が必要です。 詳細については、「内部カメラの位置の特定」を参照してください。

デバイス メタデータ パッケージの作成

内部カメラと外部カメラの両方で、デバイス メタデータ パッケージを作成する必要があります。 カメラの UWP デバイス アプリを Microsoft Store に送信する (または、内部カメラの場合は OPK を使用してプレインストールする) 場合は、アプリ自体に加えて、次を含むメタデータを提供する必要があります。

  • アプリケーションの発行元名

  • アプリケーション パッケージ名

  • アプリケーションの要素識別子

  • デバイスのエクスペリエンス識別子

デバイス メタデータを使用してデバイスにアプリを関連付ける方法の詳細については、「UWP デバイス アプリの構築」を参照してください。

UWP デバイス アプリを構築する

UWP デバイス アプリの自動インストール

ハードウェア ハンドシェイク シーケンス (ハードウェア MFT)

AVStream ミニドライバー設計ガイド

カメラ用 UWP デバイス アプリのサンプル

ドライバー MFT のサンプル