次の方法で共有


作業キューとスレッド処理の機能強化

このトピックでは、Microsoft Media Foundation プラットフォームでの作業キューとスレッド処理に関する Windows 8 の機能強化について説明します。

Windows 7 の動作

このセクションでは、Windows 7 での Media Foundation 作業キューの動作について説明します。

作業キュー

Media Foundation プラットフォームでは、いくつかの標準作業キューが作成されます。 一般的なアプリケーション用として文書化されているのは 2 つだけです。

  • MFASYNC_CALLBACK_QUEUE_STANDARD
  • MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION

アプリケーションまたはコンポーネントは、MFAllocateWorkQueue呼び出すか、MFAllocateWorkQueueEx呼び出すことによって、新しい作業キューを割り当てることができます。 MFAllocateWorkQueueEx 関数は、次の 2 種類の作業キューを定義します。

  • MF_STANDARD_WORKQUEUE は、メッセージ ループなしで作業キューを作成します。
  • MF_WINDOW_WORKQUEUE は、メッセージ ループを含む作業キューを作成します。

作業項目をキューに登録するには、MFPutWorkItem呼び出すか、MFPutWorkItemExします。 プラットフォームは、呼び出し元が提供する IMFAsyncCallbackの実装呼び出すことによって作業項目を実行します。 Windows 7 以前では、プラットフォームは作業キューごとに 1 つのスレッドを作成します。

MMCSS のサポート

マルチメディア クラス スケジューラ サービス (MMCSS) は、優先順位の低いアプリケーションに対して CPU リソースを拒否することなく、マルチメディア アプリケーションが通常の CPU 時間スライスを取得できるように、スレッドの優先順位を管理します。 MMCSS は、CPU 使用率プロファイルが異なる タスクのセットを定義します。 スレッドが MMCSS タスクに参加すると、MMCSS は次のいくつかの要因に基づいてスレッドの優先度を設定します。

  • レジストリで設定されるタスクの基本優先度。
  • AvSetMmThreadPriority呼び出すことによって実行時に設定される相対スレッド優先度。
  • アプリケーションがフォアグラウンドにあるかどうか、各 MMCSS クラスのスレッドによって消費される CPU 時間など、さまざまなランタイム特性。

アプリケーションは、MFBeginRegisterWorkQueueWithMMCSS呼び出すことによって、MMCSS に作業キューを登録できます。 この関数は、作業キュー ID、MMCSS クラス (タスク名)、MMCSS タスク識別子を受け取ります。 内部的には、タスク名とタスク ID を使用 AvSetMmThreadCharacteristics を呼び出します。 作業キューが MMCSS に登録されたら、MFGetWorkQueueMMCSSClass呼び出して、MFGetWorkQueueMMCSSTaskIdすることで、クラスとタスク ID を取得できます。

メディア セッション は、IMFWorkQueueServices インターフェイスを介して、これらの API に対するやや高いレベルのアクセスを提供します。 このインターフェイスには、次の 2 つの主要なメソッドが用意されています。

方式 形容
BeginRegisterPlatformWorkQueueWithMMCSS 作業キューを MMCSS タスクに登録します。 このメソッドは基本的に MFBeginRegisterWorkQueueWithMMCSSシン ラッパーですが、MFASYNC_CALLBACK_QUEUE_ALL 値を渡して、すべてのプラットフォーム作業キューを一度に登録できます。
BeginRegisterTopologyWorkQueuesWithMMCSS トポロジの分岐を作業キューに登録します。

 

トポロジ ブランチを登録するには、次の操作を行います。

  1. ブランチのソース ノードに MF_TOPONODE_WORKQUEUE_ID 属性を設定します。 任意のアプリケーション定義値を使用します。
  2. 必要に応じて、作業キューを MMCSS タスクに参加させる MF_TOPONODE_WORKQUEUE_MMCSS_CLASS を設定します。
  3. 解決されたトポロジ BeginRegisterTopologyWorkQueuesWithMMCSS を呼び出します。

メディア セッションは、MF_TOPONODE_WORKQUEUE_IDの一意の値ごとに新しい作業キューを割り当てます。 トポロジ ブランチごとに、非同期パイプライン操作は、ブランチに割り当てられている作業キューで実行されます。

IMFRealTimeClient

IMFRealTimeClient インターフェイスは、独自のスレッドを作成するか、非同期操作に作業キューを使用するパイプライン コンポーネントを対象としています。 メディア セッションでは、次のように、このインターフェイスを使用してパイプライン コンポーネントに正しい動作を通知します。

  • パイプライン コンポーネントがワーカー スレッドを作成する場合、IMFRealTimeClient::RegisterThreads メソッドは、参加する MMCSS クラスをコンポーネントに通知します。
  • パイプライン コンポーネントが作業キューを使用する場合、IMFRealTimeClient::SetWorkQueue メソッドは、使用する作業キューをコンポーネントに指示します。

通常、パイプライン コンポーネントはスレッドまたは作業キューを使用して非同期タスクを実行しますが、両方は実行しません。

Windows 8 の機能強化

マルチスレッド作業キュー

Windows 8 では、Media Foundation は、マルチスレッド キューと呼ばれる新しい種類の作業キューをサポートしています。 マルチスレッド キューは、システム スレッド プールを使用して作業項目をディスパッチします。 マルチスレッド キューは、前のシングルスレッド キューよりもスケーリングが優れています。 例えば

  • 複数のコンポーネントで、相互にブロックすることなくマルチスレッド キューを共有できるため、作成するスレッドが少なくて済みます。

  • 作業項目は、イベントが既に設定されている場合にコンテキストの切り替えを回避するように最適化されています。 これは、イベントを待機する独自のスレッドを作成するよりも効率的です。

IMFRealTimeClientExを使用する場合、アプリケーションはスレッドのスピンアップを回避し、代わりに作業キューを使用する必要があります。 これを実現するには、アプリケーション SetWorkQueueEx を実装し、RegisterThreadsおよび UnregisterThreads使用しないようにする必要があります。

Media Foundation プラットフォームが初期化されると、識別子が MFASYNC_CALLBACK_QUEUE_MULTITHREADEDされたマルチスレッド キューが作成されます。

マルチスレッド キューは、作業項目をシリアル化しません。 スレッド プールのスレッドが使用可能になると、キューの次の作業項目がディスパッチされます。 呼び出し元は、作業が正しくシリアル化されていることを確認する必要があります。 これを簡単にするために、Media Foundation では、シリアル作業キューを定義します。 シリアル キューは別の作業キューをラップしますが、完全にシリアル化された実行が保証されます。 キューの次の項目は、前の項目が完了するまでディスパッチされません。

次のコードでは、プラットフォームのマルチスレッド キューを介してシリアライザー キューを作成します。

DWORD workQueueID;
hr = MFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, &workQueueID); 

複数のシリアル キューで、同じマルチスレッド キューをラップできます。 シリアル キューは同じスレッド プールを共有し、シリアル化された実行は各キュー内に適用されます。

Windows 8 より前に存在していた標準作業キューは、プラットフォームのマルチスレッド キューをラップするシリアル作業キューとして実装されるようになりました。 この変更により、下位互換性が維持されます。

共有タスク作業キュー

カーネル スケジューラを正しく操作するには、使用する MMCSS タスクごとに 1 つのマルチスレッド作業キューが必要です。 Media Foundation プラットフォームは、必要に応じて、プロセスごとに MMCSS タスクごとに最大 1 つを割り当てます。 特定の MMCSS タスクの共有作業キューを取得するには、MFLockSharedWorkQueue呼び出し、タスク名を指定します。 この関数は、テーブル内のタスク名を検索します。 このタスクの作業キューがまだ存在しない場合、関数は新しい MT 作業キューを割り当てて、すぐに MMCSS タスクに参加させます。 そのタスクの作業キューが既に存在する場合、関数は既存の作業キューの識別子を返します。

待機キュー

待機キュー は、通知されるイベントを待機する特殊なプラットフォーム作業キューです。 コンポーネントがイベントの通知を待機する必要がある場合は、イベントを待機するワーカー スレッドを作成する代わりに待機キューを使用できます。

待機キューを使用するには、MFPutWaitingWorkItem呼び出します。 パラメーターには、イベント ハンドルと、IMFAsyncResultポインターが含まれます。 イベントが通知されると、待機キューによってコールバックが呼び出されます。 単一のプラットフォーム待機キューがあります。アプリケーションで独自の待機キューを作成することはできません。

MMCSS サポートの機能強化

次の新しい Media Foundation プラットフォーム機能は MMCSS に関連しています。

機能 形容
MFBeginRegisterWorkQueueWithMMCSSEx 作業キューを MMCSS に登録します。 この関数には、相対スレッド優先度を指定するパラメーターが含まれています。 内部的には、この値は AvSetMmThreadPriority呼び出しに変換されます。
MFGetWorkQueueMMCSSPriorityする 作業キューの優先順位を照会します。
MFRegisterPlatformWithMMCSS プラットフォームのすべての作業キューを MMCSS タスクに登録します。 この関数は、IMFWorkQueueServices::BeginRegisterPlatformWorkQueueWithMMCSS メソッドに似ていますが、メディア セッションのインスタンスを作成せずに使用できます。 さらに、この関数には、基本スレッドの優先順位を指定するパラメーターが含まれています。

 

メディア セッションを使用するアプリケーションでは、オーディオ レンダリング ブランチの MF_TOPONODE_WORKQUEUE_MMCSS_CLASS 属性を "Audio" に設定する必要があります。 ビデオ レンダリング ブランチの属性を "Playback" に設定します。

IMFRealTimeClientEx

IMFRealTimeClientEx インターフェイスは、非同期操作を実行するパイプライン コンポーネントの IMFRealTimeClient を置き換えます。

方式 形容
RegisterThreadsEx MMCSS にスレッドを登録するようにコンポーネントに通知します。 このメソッドは、IMFRealTimeClient::RegisterThreadsと同じですが、基本スレッド優先度のパラメーターを追加します。
SetWorkQueueEx 特定の作業キューを使用するようにコンポーネントに通知します。 このメソッドは、IMFReadTimeClient::SetWorkQueueと同じですが、作業項目の優先順位のパラメーターを追加します。
UnregisterThreads MMCSS からスレッドの登録を解除するようにコンポーネントに通知します。 このメソッドは、IMFRealTimeClient::UnregisterThreads メソッドと同じです。

 

パイプライン コンポーネントでは、次の理由により、作業キューを使用し、ワーカー スレッドを作成しないでください。

  • 作業キューは OS スレッド プールを使用するため、スケーリングが向上します。
  • プラットフォームは、MMCSS に作業キューを登録する詳細を処理します。
  • ワーカー スレッドは、デバッグが困難なデッドロックを簡単に引き起こす可能性があります。

また、非同期操作をシリアル化する必要がある場合は、シリアライザー作業キューの使用を検討してください。

トポロジ ブランチ

MF_TOPONODE_WORKQUEUE_MMCSS_CLASS 属性が MMCSS にトポロジ ブランチを登録する場合、Windows 8 ではメディア セッションで共有 MT 作業キューが使用されます。 以前のバージョンの Windows では、メディア セッションによって新しい作業キューが割り当てされました。

トポロジ ブランチを MMCSS に登録するために、2 つの新しい属性が定義されています。

属性 形容
MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY 基本スレッドの優先順位を指定します。
MF_TOPONODE_WORKQUEUE_ITEM_PRIORITY 作業項目の優先順位を指定します。

 

推奨 事項

  • メディア セッションを使用するアプリケーションでは、オーディオ レンダリング ブランチの場合は MF_TOPONODE_WORKQUEUE_MMCSS_CLASS を "Audio" に、ビデオ レンダリング ブランチの場合は "Playback" に設定する必要があります。
  • メディア セッションを使用するアプリケーションは、トポロジ IMFWorkQueueServices::BeginRegisterTopologyWorkQueuesWithMMCSS を呼び出す必要があります。
  • パイプライン コンポーネントの場合は、ワーカー スレッドではなく作業キューをお勧めします。 コンポーネントが作業キューまたはワーカー スレッドを使用する場合は、IMFRealTimeClientEx実装します。
  • プライベート作業キューは作成しないでください。これにより、プラットフォーム作業キューの目的が無効になります。 プラットフォーム マルチスレッド キューまたはプラットフォーム マルチスレッド キューをラップするシリアル キューを使用します。
  • 非同期操作をシリアル化する必要がある場合は、シリアル キューを使用します。

概要

スレッドと作業キューに関連する次の Media Foundation プラットフォーム API は、Windows 8 の新機能です。

作業キュー する