ASF メディア ソース

Media Foundation は、アプリケーションがアーキテクチャのパイプライン レイヤー内の ASF ファイルを表すために使用できる ASF メディア ソースを提供します。

ASF ファイルを再生するために、アプリケーションは ASF メディア ソースを使用して、再生パイプラインにデータをフィードできます。 エンコードシナリオでは、アプリケーションは ASF メディア ソースをソースとして使用して、別の形式に変換したり、より高いビット レート ファイルを、形式を変更せずにより低いビット レート ファイルに変換したりできます。 ASF メディア ソースはパイプライン レイヤーで使用する必要があります。つまり、アプリケーションはメディア セッションを使用して操作を制御する必要があります。 このレベルのアクセスにより、アプリケーションはメディア セッションの進行中にイベントを取得できます。 ASF コンテンツへの下位レベルのアクセスを取得するには、アプリケーションで WMContainer Layer ASF コンポーネントを使用する必要があります。

ASF メディア ソースは、Media Foundation のメディア ソースの汎用インターフェイスである IMFMediaSource インターフェイスを実装します。 他のメディア ソースと同様に、ASF メディア ソースには、主に ASF ヘッダー オブジェクトを記述するプレゼンテーション記述子が用意されています。 さらに、ASF メディア ソースは、メディア コンテンツ内の各ストリームを表すストリーム記述子を提供します。 詳細については、「 ASF ファイル構造」を参照してください。

ASF メディア ソースの作成

ASF メディア ソースを作成するには、アプリケーションで ソース リゾルバーを使用する必要があります。 ASF メディア ソースを作成するには、ソース リゾルバーが ASF メディア ソースを作成するソースをアプリケーションが提供する必要があります。 ソース情報は、ソース ファイルの URL またはメディアを含むバイト ストリームを指定することによって提供する必要があります。 アプリケーションで URL を指定して ASF メディア ソースを作成する場合は、同期操作のために IMFSourceResolver::CreateObjectFromURL を呼び出すか、 IMFSourceResolver::Begin..を呼び出す必要があります。非同期操作の EndCreateObjectFromURL 。 バイト ストリームからメディア ソースを作成するプロセスは似ています。 アプリケーションは、同期操作のために IMFSourceResolver::CreateObjectFromByteStream を呼び出すか、 IMFSourceResolver::Begin... を呼び出す必要があります。非同期操作の EndCreateObjectFromBytestream 。 これらの呼び出しでは、 dwFlags パラメーターでMF_RESOLUTION_MEDIASOURCEを指定する必要があります。 このフラグの使用方法の詳細については、「ソース リゾルバーの使用」を参照してください。

アプリケーションでローカル ファイルの URL を指定する場合、URL 文字列にはメディア ファイルのパスを含めることができます。または、プレフィックスとして "file: "scheme" を付けることができます。 ファイル名拡張子は、".asf"、".wm"、L".wma"、または ".wmv" である必要があります。 ネットワーク上の ASF ファイルの場合、ソース リゾルバーは、ASF メディア ソースを使用する ネットワーク ソースを作成します。

オブジェクト作成プロセス中、ソース リゾルバーは、システム レジストリ内のスキーム ハンドラーとバイト ストリーム ハンドラーの一覧を検索し、メディア コンテンツを解析し、その下にメディア ソース オブジェクトを作成できる最も近い一致ハンドラーを読み込みます。 メディア ソース (URL とバイト ストリーム) の作成に使用されるメソッドに関係なく、ソース リゾルバーはバイト ストリームを作成し、ソース メディアの内容をバイト ストリームに読み取ります。 詳細については、「 スキーム ハンドラー」と「Byte-Stream ハンドラー」を参照してください。

メディア ソースを作成する方法のコード例については、「 ソース リゾルバーの使用」を参照してください。

ASF メディア ソースの構成設定

ソース リゾルバーは、基になるバイト ストリームの機能を照会し、新しく作成されたメディア ソースで操作が許可されていることを確認します。 そのような機能の 1 つは、シークです。 シーク操作が許可されている場合、アプリケーションは、プレゼンテーション内の特定のポイントをシークするときにメディア ソースが使用するシーク モードを指定できます。

アプリケーションは、オブジェクトの作成時にメディア ソースで使用するシーク モードを設定できます。 ASF メディア ソースを指定したシーク モードで作成した後、メディア ソースで変更したり、プレゼンテーション中に動的に変更したりすることはできません。 シーク設定は、メディア ソースの作成に使用される関連するソース リゾルバー メソッドに対するアプリケーションの呼び出しでプロパティとして指定されます。 これらの一連のプロパティは、プロパティ ストアで設定され、 pProps パラメーターに渡されます。 これらのプロパティが渡されない場合、メディア ソースは既定の設定で機能します。 これらのプロパティの設定の詳細については、「 メディア ソースの構成」を参照してください。

シークが許可されている場合、ASF メディア ソースは次のシーク モードをサポートします。

  • 正確なシーク: このモードでは、ASF メディア ソースは ASF ファイルの ASF インデックス オブジェクトに依存します。 ファイルに Index オブジェクトがない場合、正確なシークは無効になり、メディア ソースに設定されているアプリケーション指定のプロパティに応じて他のモードのいずれかが使用されます。
  • 概算シーク: このモードは、プロパティ ストア内 のMFPKEY_ASFMediaSource_ApproxSeek を関連するソース リゾルバー メソッドに渡すことによって、アプリケーションによって要求されます。 ただし、おおよそのシークは、バイト ストリームが時間ベースのシークをサポートしていない場合にのみ使用されます。 このモードでは、メディア ソースによって、シーク時間に比較的近い開始時刻が決定されます。 ASF ファイルに ASF インデックス オブジェクトが含まれている場合は、開始時刻の計算に使用されます。 おおよそのシークは精度は低くなりますが、正確なシークよりも高速です。これは、所定の開始時刻に最初のサンプルをレンダリングする時間が短いためです。
  • 反復シーク: このモードを設定するには、アプリケーションで MFPKEY_ASFMediaSource_IterativeSeekIfNoIndex プロパティを設定する必要があります。 反復シークは、ASF インデックス オブジェクトを含まない ASF ファイル内の位置を検索するアルゴリズムです。 このモードでは、メディア ソースはバイト ストリーム オフセットを読み取ることによってシーク ポイントの大まかな推定値を決定します。 平均ビットレートに基づいて一連の近似値を使用して、ターゲットシーク時間に徐々に近づけます。 (アルゴリズムはバイナリ検索に似ています)。反復シークは、Index オブジェクトを使用してシークするよりも時間がかかる可能性があるため、既定では無効になっています。 このプロパティを設定する場合は、次のプロパティを使用して検索パラメーターを設定します: MFPKEY_ASFMediaSource_IterativeSeek_Max_CountMFPKEY_ASFMediaSource_IterativeSeek_Tolerance_In_MilliSecond。 これらのプロパティは、反復の最大数と許容度をそれぞれ設定します。 アルゴリズムは、イテレーションの最大数に達したとき、またはシーク時間からの距離が指定された許容範囲内にあるパケットを検出すると停止します。

簡単に言うと、アプリケーションには、ASF ファイルに ASF インデックス オブジェクトが含まれていない場合に、近似シークまたは反復シークを選択するオプションがあります。

ASF メディア ソース オブジェクト モデル

ASF メディア ソースは 、IMFMediaSource インターフェイスを実装し、次のインターフェイスを公開します。 アプリケーションは、ASF メディア ソースで IMFMediaSource::QueryInterface を呼び出すことによって、これらのインターフェイスへの参照を取得できます。

インターフェイス 説明
IMFMediaSource すべてのメディア ソースに必要です。
IMFMediaEventGenerator すべてのメディア ソースに必要です。 アプリケーションがメディア セッションを介してメディア ソースからイベントを取得できるようにします。
IMFGetService 指定したサービス インターフェイスのメディア ソースに対してクエリを実行します。
IPropertyStore メディア ソースのプロパティを設定および取得します。 各プロパティには、わかりやすい名前と値が含まれています。
IMFMetadata ASF ファイルのメタデータについて説明します。
IMFMetadataProvider プレゼンテーション全体、またはプレゼンテーション内の 1 つのストリームのメタデータのコレクションを取得します。
IMFRateSupport 逆再生など、サポートされている再生速度の範囲を照会します。
IMFRateControl 再生速度を取得または設定します。
IMFTrustedInput ソースに含まれる各 ASF ストリームの ITA を取得します。
IMFPMPClient メディア ソースが IMFPMPHost インターフェイスへのポインターを受け取り、PMP プロセスでオブジェクトを作成するために使用できるようにします。
IMFTimecodeTranslate 映画学会とテレビ エンジニア協会 (SMPTE) の時間コードと 100 ナノ秒の時間単位を変換します。

 

ASF Media Source Services

ASF メディア ソースは、ASF ファイルを対象とするさまざまなサービスを提供します。 特定のサービスへのポインターを取得するには、アプリケーションで MFGetService の呼び出しで次のいずれかのサービス識別子を使用する必要があります。 詳細については、「 サービス インターフェイス」を参照してください。

サービス識別子 説明
MF_RATE_CONTROL_SERVICE この識別子を使用すると、アプリケーションは IMFRateSupport インターフェイスまたは IMFRateControl インターフェイスへのポインターを取得できます。 メディア ソースによって実装されたレート サポート オブジェクトを使用すると、基になる ASF メディア ファイルで特定のレートがサポートされている場合に、アプリケーションがチェックできます。 レート制御オブジェクトを使用することで、アプリケーションは再生速度を取得および設定できます。 アプリケーションで再生用の特定のレートが指定されている場合、ASF メディア ソースは最初に、要求されたレートがレート制限内にあるかどうかを確認し (高速で最も遅いレートによって決定されます)、レートを設定します。 これは、ネットワーク帯域幅に応じてビットレートが変化する可能性があるため、可変条件ではチェックされません。 詳細については、「 レート制御」を参照してください
MF_METADATA_PROVIDER_SERVICE この識別子を使用すると、アプリケーションは ASF メディア ソースの IMFMetadataProvider インターフェイスへのポインターを取得できます。 このインターフェイスは、ASF ファイルに関する情報、特に ASF ヘッダー オブジェクトとメディア コンテンツ内に含まれるストリームへのアクセスを提供します。 ヘッダー情報はプレゼンテーション記述子属性を介して公開され、ストリーム情報はストリーム記述子属性を介して提供されます。 これらの属性の詳細については、「 ASF ヘッダー オブジェクトの Media Foundation 属性」を参照してください。 属性を介して公開される情報に加えて、プロパティとして設定される説明メタデータも存在します。
MF_PROPERTY_HANDLER_SERVICE この識別子を使用すると、アプリケーションは ASF メディア ソースの IPropertyStore インターフェイスへのポインターを取得できます。 プロパティ ストアには、ASF ファイルに関連するすべてのメタデータが含まれています。 この識別子は Windows 7 の新機能であり、メタデータ プロパティを取得するためのMF_METADATA_PROVIDER_SERVICEに置き換えられます。
MFNETSOURCE_STATISTICS_SERVICE 詳細については、「 クライアント ログでのネットワーク統計情報の取得」を参照してください。
MF_TIMECODE_SERVICE この識別子を使用すると、アプリケーションはメディア ソースの IMFTimecodeTranslate インターフェイスへのポインターを取得できます。 この実装は、SMPTE タイム コードを 100 ナノ秒単位に変換して戻すなどのタイム コード変換を実行するために使用できます。

 

タイムコード変換

ASF メディア ソースには、アプリケーションで SMPTE タイム コードを最も近いプレゼンテーション時間 (100 ナノ秒単位) に変換できるタイム コード変換サービスが用意されています。 逆に、アプリケーションは、要求されたプレゼンテーション時間のタイム コードを取得することもできます。 サービスは、ASF メディア ソースが実装する IMFTimecodeTranslate インターフェイスを介して使用できます。 このインターフェイス ポインターのメソッド呼び出しは非同期であり、アプリケーションのユーザー インターフェイスをブロックすることなく、メインアプリケーション スレッドから実行できます。

次の手順は、タイム コード変換の手順をまとめたものです。

  1. MFGetService を呼び出し、MF_TIMECODE_SERVICE識別子を指定して、ASF メディア ソースの IMFTimecodeTranslate インターフェイスへのポインターを取得します。
  2. IMFTimecodeTranslate::BeginConvertTimecodeToHNS または IMFTimecodeTranslate::BeginConvertHNSToTimecode を呼び出し、変換する時刻を指定します。 BeginConvertTimecodeToHNS の場合、時刻コードは、VT_I8データ型を持つ PROPVARIANT 変数として指定する必要があります。 BeginConvertHNSToTimecode メソッドでは、MFTIME 型として 100 ナノ秒単位の時間が必要です。
  3. IMFTimecodeTranslate::EndConvertTimecodeToHNS または IMFTimecodeTranslate::EndConvertTimecodeToHNS を適切に呼び出して、非同期操作を完了します。

メディア ソースの作成中に、ソース リゾルバーは、メディア ソースが ASF コンテンツを読み取るファイルのバイト ストリームを作成します。 時間変換を成功させるには、ASF ファイルに関連付けられているバイト ストリームにシーク機能が必要です。それ以外の場合、アプリケーションは Begin... 呼び出しからMF_E_BYTESTREAM_NOT_SEEKABLE エラーを取得します。 時間変換のもう 1 つの要件は、ASF メディア ソースによって表される ASF ファイルに ASF インデックス オブジェクトが必要であることです。 プレゼンテーションの時刻と時刻コードは、ASF ファイルのすべてのインデックスと対応するシーク ポイントを保持する ASF インデックス オブジェクトから抽出されます。 プレゼンテーション時のコード変換の場合、ASF ファイルには Simple Index オブジェクトが含まれている必要があります。時刻コードからプレゼンテーションへの時間変換の場合、ASF ファイルには Index オブジェクトが必要です。 変換操作は、ASF ファイルに関連付けられている Index オブジェクトを解析して読み取るために、基になる インデクサー (WMContainer コンポーネント) に依存します。 ファイルに Index オブジェクトが含まれていない場合、アプリケーションはMF_E_NO_INDEXエラー コードを非同期的に受け取ります。

アプリケーションによって要求された時間を変換するために、メディア ソースはファイル内のストリームを列挙し、適切な ASF インデックス オブジェクトを含むストリームを検索します。 このようなストリームが見つかった場合、メディア ソースはストリームの ASF パケットを解析し、正しい時間コードに達するまで解析します。 正しいサンプルが見つかると、対応するプレゼンテーション時間または時間コードがサンプルから取得され、呼び出し元に返されます。

スクリプト コマンドのサポート

スクリプト ストリームを含む ASF トポロジを構築すると、スクリプト ストリーム ノードがトポロジに追加されます。 このノードは、適切なタイミングで IMFSamples を送信します。 スクリプト ソース ノードによって提供される IMFSample は、サンプルに関連付けられている IMFMediaBuffer にデータを格納します。 サンプルで CopyToBuffer を呼び出して IMFMediaBuffer を取得し、バッファーで Lock を呼び出してデータを取得できます。

スクリプト ストリームペイロードは、型文字列としてバッファーにパックされ、その後に NULL が続き、コマンド文字列が続き、その後に NULL が続きます。 文字列は ASF 形式の Unicode です。

たとえば、ペイロードは次のようになります (\0 は NULL 文字を示します)。

URL\0http://contoso.com\0

Text\0これはキャプション\0 です

パイプライン レイヤーの ASF コンポーネント

Media Foundation での ASF サポート