IMFASFIndexer
COM公式ドキュメント
Systems Format (ASF) ファイル内のインデックスを操作するためのメソッドを提供します。
解説(Remarks)
インデクサーオブジェクトを使用すると、既存の ASF インデックスの読み取りや、新しいインデックスの書き込みを行えます。インデックスオブジェクトには、読み取りモードと書き込みモードという相互排他的な 2 つのモードがあります。モードを設定するには SetFlags を呼び出します。
インデクサーオブジェクトを構成するには、次のメソッドを使用します (両モード共通):
既存のインデックスを読み取るには、次のメソッドを使用します: インデックスを書き込むには、次のメソッドを使用します:メソッド 13
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
インデクサーのオプションを設定します。
| dwFlags | DWORD | in | 使用するインデクサーオプションを指定する、MFASF_INDEXER_FLAGS 列挙体の 0 個以上のフラグのビットごとの OR。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| インデクサーオブジェクトに対してフラグを設定する前に、そのオブジェクトが初期化されました。詳細については「解説」を参照してください。 |
解説(Remarks)
IMFASFIndexer::SetFlags は IMFASFIndexer::Initialize より前に呼び出す必要があります。Initialize の後に SetFlags を呼び出そうとすると、結果として MF_E_INVALIDREQUEST が返されます。
選択されているインデクサーオプションを示すフラグを取得します。
| pdwFlags | DWORD* | out | MFASF_INDEXER_FLAGS 列挙体の 0 個以上のフラグのビットごとの OR を受け取ります。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| pdwFlags が NULL です。 |
解説(Remarks)
IMFASFIndexer::Initialize でインデクサーオブジェクトを初期化する前に、このメソッドを呼び出す必要があります。
インデクサーオブジェクトを初期化します。
| pIContentInfo | IMFASFContentInfo* | in | インデクサーで使用するコンテンツを記述する ContentInfo オブジェクトの IMFASFContentInfo インターフェイスへのポインター。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| 無効な ASF データです。 | |
| 予期しないエラーです。 |
解説(Remarks)
インデクサーは、コンテンツのインデックスを正しく書き込みまたは読み取りするために、ContentInfo オブジェクト内のデータを調べる必要があります。インデクサーはコンテンツ情報を変更せず、また IMFASFContentInfo インターフェイスへの参照を保持しません。
ASF ヘッダーでは、最大データパケットサイズが最小データパケットサイズと等しくなければなりません。そうでない場合、このメソッドは MF_E_UNEXPECTED を返します。
コンテンツの先頭からのインデックスオブジェクトのオフセットを取得します。
| pIContentInfo | IMFASFContentInfo* | in | コンテンツを記述する ContentInfo オブジェクトの IMFASFContentInfo インターフェイスへのポインター。 |
| pcbIndexOffset | ULONGLONG* | out | ContentInfo オブジェクトが記述するコンテンツの先頭を基準としたインデックスのオフセットを受け取ります。これは ASF ファイルの先頭を基準とした位置です。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| pIContentInfo が NULL であるか、pcbIndexOffset が NULL です。 |
解説(Remarks)
インデックスは、このメソッドで取得したオフセットからファイルの末尾まで続きます。
このメソッドを呼び出す前に、IMFASFIndexer::Initialize を呼び出してインデクサーをセットアップする必要があります。
IMFASFIndexer::GetCompletedIndex を複数回呼び出してインデックスを取得する場合、個々のインデックス部分の位置は、インデックスオフセットにインデックス内でのその部分のオフセットを加えた値と等しくなります。
インデックス対象のバイトストリームを追加します。
| ppIByteStreams | IMFByteStream** | in | IMFByteStream インターフェイスポインターの配列。バイトストリームを取得するには、MFCreateASFIndexerByteStream を呼び出します。 |
| cByteStreams | DWORD | in | ppIByteStreams 配列内のポインターの数。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| インデクサーオブジェクトはすでに初期化されており、インデックス化されたパケットを保持しています。 |
解説(Remarks)
読み取りシナリオでは、インデクサーオブジェクトが使用するバイトストリームは 1 つのみである必要があります。インデックス生成シナリオでは、生成する必要があるインデックスオブジェクトの数によって異なります。
インデクサーオブジェクトが使用しているバイトストリームの数を取得します。
| pcByteStreams | DWORD* | out | インデクサーオブジェクトが使用しているバイトストリームの数を受け取ります。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| pcByteStreams が NULL です。 |
指定したストリームおよびインデックスの種類について、インデックス設定を取得します。
| pIndexIdentifier | ASF_INDEX_IDENTIFIER* | in | ステータスを取得する対象のストリーム番号とインデックスの種類を含む ASF_INDEX_IDENTIFIER 構造体へのポインター。 |
| pfIsIndexed | BOOL* | out | pIndexIdentifier で記述されたインデックスが作成済みかどうかを指定するブール値を取得する変数。 |
| pbIndexDescriptor | BYTE* | out | インデックス記述子を受け取るバッファー。インデックス記述子は、ASF_INDEX_DESCRIPTOR 構造体と、その後に続く任意のインデックス固有データで構成されます。 |
| pcbIndexDescriptor | DWORD* | inout | 入力時には、pbIndexDescriptor が指すバッファーのサイズ (バイト単位) を指定します。pbIndexDescriptor が NULL の場合、この値は 0 にできます。出力時には、インデックス記述子のサイズ (バイト単位) を受け取ります。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| pcbIndexDescriptor に指定されたバッファーサイズが小さすぎます。 |
解説(Remarks)
既存の ASF インデックスを読み取るには、このメソッドを呼び出す前に IMFASFIndexer::SetIndexByteStreams を呼び出します。
ストリームのインデックスが存在し、pcbIndexDescriptor に渡された値が pbIndexDescriptor バッファーに必要なサイズより小さい場合、このメソッドは MF_E_BUFFERTOOSMALL を返します。必要なバッファーサイズは pcbIndexDescriptor パラメーターで返されます。
指定したストリームのインデックスが存在しない場合、このメソッドは pfIsIndexed パラメーターに FALSE を返します。
ストリームのインデックスを構成します。
| pbIndexDescriptor | BYTE* | in | 設定するインデックス記述子。インデックス記述子は、ASF_INDEX_DESCRIPTOR 構造体と、その後に続く任意のインデックス固有データです。 |
| cbIndexDescriptor | DWORD | in | インデックス記述子のサイズ (バイト単位)。 |
| fGenerateIndex | BOOL | in | ブール値。インデックス記述子で指定されたストリームに対して、指定した種類のインデックスをインデクサーに作成させるには TRUE に設定します。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| シーク専用シナリオでインデックスステータスを変更しようとしました。詳細については「解説」を参照してください。 |
解説(Remarks)
IMFASFIndexer::GenerateIndexEntries を呼び出す前に、SetIndexStatus の呼び出しをすべて行う必要があります。
インデクサーオブジェクトは、既定では各ストリームに対して時間ベースのインデックスを作成するように構成されています。既定の設定を上書きする場合にのみ、このメソッドを呼び出してください。
このメソッドはインデックス読み取りシナリオでは使用できません。インデックスを書き込む場合にのみ使用できます。
目的のシーク時刻を指定すると、クライアントがデータの読み取りを開始すべきオフセットを取得します。
| pvarValue | PROPVARIANT* | in | 位置を取得する対象のインデックスエントリの値。この値の形式は、インデックス識別子で指定されるインデックスの種類によって異なります。時間ベースのインデックスの場合、バリアント型は VT_I8 であり、値は目的のシーク時刻 (100 ナノ秒単位) です。 |
| pIndexIdentifier | ASF_INDEX_IDENTIFIER* | in | ストリーム番号とインデックスの種類を識別する ASF_INDEX_IDENTIFIER 構造体へのポインター。 |
| pcbOffsetWithinData | ULONGLONG* | out | ASF Data Object のデータセグメント内のオフセットを受け取ります。オフセットはバイト単位で、パケット 0 の先頭を基準とします。このオフセットは、クライアントがストリームからの読み取りを開始すべき開始位置を示します。この位置は、要求されたシーク時刻に正確に対応しない場合があります。 逆再生の場合、目的のシーク位置より後にキーフレームが存在しないときは、このパラメーターは MFASFINDEXER_READ_FOR_REVERSEPLAYBACK_OUTOFDATASEGMENT の値を受け取ります。その場合、シーク位置はデータセグメントの末尾を 1 バイト超えた位置になります。 |
| phnsApproxTime | LONGLONG* | inout | pcbOffsetWithinData パラメーターで返されるオフセットに位置するデータの、おおよそのタイムスタンプを受け取ります。この値の精度は ASF インデックスのインデックス化間隔と等しく、通常は約 1 秒です。
|
| pdwPayloadNumberOfStreamWithinPacket | DWORD* | inout | 指定したストリームの情報を含むペイロードのペイロード番号を受け取ります。パケットには複数のペイロードを含めることができ、それぞれが異なるストリームのデータを含みます。このパラメーターは NULL にできます。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| 要求されたシーク時刻が範囲外です。 | |
| 指定したストリームに対して、指定した種類のインデックスが存在しません。 |
ファイルの ASF パケットを受け取り、それらに対するインデックスエントリを作成します。
| pIASFPacketSample | IMFSample* | in | ASF パケットを含むメディアサンプルの IMFSample インターフェイスへのポインター。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| 渡された引数が NULL です。 | |
| インデクサーが初期化されていません。 |
解説(Remarks)
ASF インデクサーは、ファイルのインデックスを内部で作成します。インデクサーに送信されたすべてのデータパケットに対する完成したインデックスを取得するには、IMFASFIndexer::CommitIndex でインデックスをコミットし、次に IMFASFIndexer::GetCompletedIndex を呼び出してインデックスエントリをメディアバッファーに書き込みます。インデックスを保持できる十分な大きさのバッファーを割り当てられるようにインデックスのサイズを判断するには、IMFASFIndexer::GetIndexWriteSpace を呼び出します。
このメソッドがインデックスエントリを作成すると、それらは IMFASFIndexer::GetSeekPositionForValue によって直ちに使用可能になります。
pIASFPacketSample で指定するメディアサンプルは、単一の ASF パケットを含むバッファーを保持していなければなりません。IMFASFMultiplexer::GetNextPacket メソッドを呼び出して、ASF マルチプレクサーからサンプルを取得します。
このメソッドはインデックスの読み取り中には使用できず、インデックスの書き込み時にのみ使用できます。
ASF コンテンツに関連付けられた ContentInfo オブジェクトに、新しいインデックスに関する情報を追加します。後でインデクサーがインデックスを読み取れるようにするため、インデックスをコンテンツにコピーする前にこのメソッドを呼び出す必要があります。
| pIContentInfo | IMFASFContentInfo* | in | コンテンツを記述する ContentInfo オブジェクトの IMFASFContentInfo インターフェイスへのポインター。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| 呼び出し元が無効な要求を行いました。詳細については「解説」を参照してください。 |
解説(Remarks)
インデックスが正しく機能するためには、IMFASFIndexer::GenerateIndexEntries メソッドを使用してファイル内のすべての ASF パケットをインデクサーに渡した後に、このメソッドを呼び出す必要があります。このメソッドを呼び出した後は、GetCompletedIndex を呼び出してインデックスを取得し、ファイル内の適切な場所に書き込む必要があります。最後に、ASF ContentInfo オブジェクトの IMFASFContentInfo::GenerateHeader メソッドを呼び出して、新しい ASF ヘッダーを生成する必要があります。
アプリケーションは、新しいインデックスを書き込む場合にのみ CommitIndex メソッドを使用しなければなりません。そうでない場合、CommitIndex は結果として MF_E_INVALIDREQUEST を返すことがあります。たとえば、アプリケーションがインデクサーオブジェクトに MFASF_INDEXER_WRITE_NEW_INDEX 以外のフラグを設定している場合、MF_E_INVALIDREQUEST が返されます。また、以前の CommitIndex 呼び出しでインデックスエントリがすでにコミットされている場合にも、CommitIndex は MFASF_INDEXER_WRITE_NEW_INDEX を返すことがあります。
このメソッドはインデックス読み取りシナリオでは使用できません。インデックスを書き込む場合にのみ使用できます。
完成したインデックスを格納するために必要なバッファーのサイズ (バイト単位) を取得します。
| pcbIndexWriteSpace | ULONGLONG* | out | インデックスのサイズ (バイト単位) を受け取ります。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| インデックスがコミットされていません。詳細については「解説」を参照してください。 |
解説(Remarks)
このメソッドを使用してインデックスのサイズを取得し、それを保持できる十分な大きさのバッファーを割り当てます。
IMFASFIndexer::GetIndexWriteSpace を呼び出す前に、IMFASFIndexer::CommitIndex の呼び出しによってインデックスをコミットする必要があります。GetIndexWriteSpace を呼び出す前にインデックスがコミットされていない場合、結果として MF_E_INDEX_NOT_COMMITTED が返されます。
完成したインデックスをメディアバッファーに書き込むには、IMFASFIndexer::GetCompletedIndex を呼び出します。
このメソッドは読み取りシナリオでは使用できません。インデックスを書き込む場合にのみ使用できます。
ASF インデクサーオブジェクトから、完成したインデックスを取得します。
| pIIndexBuffer | IMFMediaBuffer* | in | インデックスデータを受け取るメディアバッファーの IMFMediaBuffer インターフェイスへのポインター。 |
| cbOffsetWithinIndex | ULONGLONG | in | 取得するデータのオフセット (インデックスデータの先頭からのバイト単位)。最初の呼び出しでは 0 に設定します。以降の呼び出しが必要な場合 (バッファーがインデックス全体を保持できるほど大きくない場合)、最後に取得したバイトの次のバイトに設定します。 |
戻り値
このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。
| 戻り値 | 説明 |
|---|---|
| メソッドは成功しました。 | |
| 完成したインデックスを取得しようとする前に、インデックスがコミットされていませんでした。詳細については「解説」を参照してください。 |
解説(Remarks)
このメソッドはバッファーを可能な限り使用し、バッファーの長さを適切に更新します。
pIIndexBuffer がバッファー全体を格納できるほど大きい場合、cbOffsetWithinIndex は 0 にし、呼び出しは 1 回だけ行えば済みます。それ以外の場合、連続するバッファー間にギャップがあってはなりません。
ユーザーはこのデータを、ASF データオブジェクトの末尾から cbOffsetFromIndexStart バイト後の位置でコンテンツに書き込む必要があります。ASF インデックスの開始位置を判断するには、IMFASFIndexer::GetIndexPosition を呼び出します。
この呼び出しは、IMFASFIndexer::CommitIndex が呼び出されていない限り成功しません。GetCompletedIndex を呼び出した後、呼び出し元は IMFASFContentInfo::GenerateHeader を呼び出し、既存の ASF ヘッダーを新しいヘッダーで上書きする必要があります。そうしないと、ASF ヘッダーがコンテンツと一致せず、ファイルが正しく再生される保証はありません。
このメソッドはインデックス読み取りシナリオでは使用できません。インデックスを書き込む場合にのみ使用できます。
例
次の例は、完全な ASF インデックスをバイトストリームに書き込む方法を示します。
HRESULT WriteASFIndex(IMFASFIndexer *pIndex,IMFByteStream *pStream)
{
const DWORD cbChunkSize = 4096;
IMFMediaBuffer *pBuffer = NULL;
QWORD cbIndex = 0;
DWORD cbIndexWritten = 0;
HRESULT hr = pIndex->GetIndexWriteSpace(&cbIndex);
if (FAILED(hr))
{
goto done;
}
hr = MFCreateMemoryBuffer(cbChunkSize, &pBuffer);
if (FAILED(hr))
{
goto done;
}
while (cbIndexWritten < cbIndex)
{
BYTE *pData = NULL;
DWORD cbData = 0;
DWORD cbWritten = 0;
hr = pIndex->GetCompletedIndex(pBuffer, cbIndexWritten);
if (FAILED(hr))
{
goto done;
}
hr = pBuffer->Lock(&pData, NULL, &cbData);
if (FAILED(hr))
{
goto done;
}
hr = pStream->Write(pData, cbData, &cbWritten);
(void)pBuffer->Unlock();
if (FAILED(hr))
{
goto done;
}
cbIndexWritten += cbData;
}
done:
SafeRelease(&pBuffer);
return hr;
};
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IMFASFIndexer "{53590F48-DC3B-4297-813F-787761AD7B3E}" #usecom global IMFASFIndexer IID_IMFASFIndexer "{}" #comfunc global IMFASFIndexer_SetFlags 3 int #comfunc global IMFASFIndexer_GetFlags 4 var #comfunc global IMFASFIndexer_Initialize 5 sptr #comfunc global IMFASFIndexer_GetIndexPosition 6 sptr,var #comfunc global IMFASFIndexer_SetIndexByteStreams 7 sptr,int #comfunc global IMFASFIndexer_GetIndexByteStreamCount 8 var #comfunc global IMFASFIndexer_GetIndexStatus 9 var,var,var,var #comfunc global IMFASFIndexer_SetIndexStatus 10 var,int,int #comfunc global IMFASFIndexer_GetSeekPositionForValue 11 var,var,var,var,var #comfunc global IMFASFIndexer_GenerateIndexEntries 12 sptr #comfunc global IMFASFIndexer_CommitIndex 13 sptr #comfunc global IMFASFIndexer_GetIndexWriteSpace 14 var #comfunc global IMFASFIndexer_GetCompletedIndex 15 sptr,int64 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IMFASFIndexer "{53590F48-DC3B-4297-813F-787761AD7B3E}" #usecom global IMFASFIndexer IID_IMFASFIndexer "{}" #comfunc global IMFASFIndexer_SetFlags 3 int #comfunc global IMFASFIndexer_GetFlags 4 sptr #comfunc global IMFASFIndexer_Initialize 5 sptr #comfunc global IMFASFIndexer_GetIndexPosition 6 sptr,sptr #comfunc global IMFASFIndexer_SetIndexByteStreams 7 sptr,int #comfunc global IMFASFIndexer_GetIndexByteStreamCount 8 sptr #comfunc global IMFASFIndexer_GetIndexStatus 9 sptr,sptr,sptr,sptr #comfunc global IMFASFIndexer_SetIndexStatus 10 sptr,int,int #comfunc global IMFASFIndexer_GetSeekPositionForValue 11 sptr,sptr,sptr,sptr,sptr #comfunc global IMFASFIndexer_GenerateIndexEntries 12 sptr #comfunc global IMFASFIndexer_CommitIndex 13 sptr #comfunc global IMFASFIndexer_GetIndexWriteSpace 14 sptr #comfunc global IMFASFIndexer_GetCompletedIndex 15 sptr,int64 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。