Win32 API 日本語リファレンス
ホームMedia.MediaFoundation › IMFASFIndexer

IMFASFIndexer

COM
IID53590f48-dc3b-4297-813f-787761ad7b3e継承元IUnknown自前メソッド開始 vtbl3

公式ドキュメント

Systems Format (ASF) ファイル内のインデックスを操作するためのメソッドを提供します。

解説(Remarks)

インデクサーオブジェクトを使用すると、既存の ASF インデックスの読み取りや、新しいインデックスの書き込みを行えます。インデックスオブジェクトには、読み取りモードと書き込みモードという相互排他的な 2 つのモードがあります。モードを設定するには SetFlags を呼び出します。

インデクサーオブジェクトを構成するには、次のメソッドを使用します (両モード共通):

既存のインデックスを読み取るには、次のメソッドを使用します: インデックスを書き込むには、次のメソッドを使用します:

メソッド 13

vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。

vtbl 3 HRESULT SetFlags(DWORD dwFlags)

インデクサーのオプションを設定します。

dwFlagsDWORDin使用するインデクサーオプションを指定する、MFASF_INDEXER_FLAGS 列挙体の 0 個以上のフラグのビットごとの OR。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
MF_E_INVALIDREQUEST
インデクサーオブジェクトに対してフラグを設定する前に、そのオブジェクトが初期化されました。詳細については「解説」を参照してください。

解説(Remarks)

IMFASFIndexer::SetFlagsIMFASFIndexer::Initialize より前に呼び出す必要があります。Initialize の後に SetFlags を呼び出そうとすると、結果として MF_E_INVALIDREQUEST が返されます。

vtbl 4 HRESULT GetFlags(DWORD* pdwFlags)

選択されているインデクサーオプションを示すフラグを取得します。

pdwFlagsDWORD*outMFASF_INDEXER_FLAGS 列挙体の 0 個以上のフラグのビットごとの OR を受け取ります。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_INVALIDARG
pdwFlagsNULL です。

解説(Remarks)

IMFASFIndexer::Initialize でインデクサーオブジェクトを初期化する前に、このメソッドを呼び出す必要があります。

vtbl 5 HRESULT Initialize(IMFASFContentInfo* pIContentInfo)

インデクサーオブジェクトを初期化します。

pIContentInfoIMFASFContentInfo*inインデクサーで使用するコンテンツを記述する ContentInfo オブジェクトの IMFASFContentInfo インターフェイスへのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
MF_E_ASF_INVALIDDATA
無効な ASF データです。
MF_E_UNEXPECTED
予期しないエラーです。

解説(Remarks)

インデクサーは、コンテンツのインデックスを正しく書き込みまたは読み取りするために、ContentInfo オブジェクト内のデータを調べる必要があります。インデクサーはコンテンツ情報を変更せず、また IMFASFContentInfo インターフェイスへの参照を保持しません。

ASF ヘッダーでは、最大データパケットサイズが最小データパケットサイズと等しくなければなりません。そうでない場合、このメソッドは MF_E_UNEXPECTED を返します。

vtbl 6 HRESULT GetIndexPosition(IMFASFContentInfo* pIContentInfo, ULONGLONG* pcbIndexOffset)

コンテンツの先頭からのインデックスオブジェクトのオフセットを取得します。

pIContentInfoIMFASFContentInfo*inコンテンツを記述する ContentInfo オブジェクトの IMFASFContentInfo インターフェイスへのポインター。
pcbIndexOffsetULONGLONG*outContentInfo オブジェクトが記述するコンテンツの先頭を基準としたインデックスのオフセットを受け取ります。これは ASF ファイルの先頭を基準とした位置です。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_INVALIDARG
pIContentInfoNULL であるか、pcbIndexOffsetNULL です。

解説(Remarks)

インデックスは、このメソッドで取得したオフセットからファイルの末尾まで続きます。

このメソッドを呼び出す前に、IMFASFIndexer::Initialize を呼び出してインデクサーをセットアップする必要があります。

IMFASFIndexer::GetCompletedIndex を複数回呼び出してインデックスを取得する場合、個々のインデックス部分の位置は、インデックスオフセットにインデックス内でのその部分のオフセットを加えた値と等しくなります。

vtbl 7 HRESULT SetIndexByteStreams(IMFByteStream** ppIByteStreams, DWORD cByteStreams)

インデックス対象のバイトストリームを追加します。

ppIByteStreamsIMFByteStream**inIMFByteStream インターフェイスポインターの配列。バイトストリームを取得するには、MFCreateASFIndexerByteStream を呼び出します。
cByteStreamsDWORDinppIByteStreams 配列内のポインターの数。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
MF_E_ALREADY_INITIALIZED
インデクサーオブジェクトはすでに初期化されており、インデックス化されたパケットを保持しています。

解説(Remarks)

読み取りシナリオでは、インデクサーオブジェクトが使用するバイトストリームは 1 つのみである必要があります。インデックス生成シナリオでは、生成する必要があるインデックスオブジェクトの数によって異なります。

vtbl 8 HRESULT GetIndexByteStreamCount(DWORD* pcByteStreams)

インデクサーオブジェクトが使用しているバイトストリームの数を取得します。

pcByteStreamsDWORD*outインデクサーオブジェクトが使用しているバイトストリームの数を受け取ります。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_INVALIDARG
pcByteStreamsNULL です。
vtbl 9 HRESULT GetIndexStatus(ASF_INDEX_IDENTIFIER* pIndexIdentifier, BOOL* pfIsIndexed, BYTE* pbIndexDescriptor, DWORD* pcbIndexDescriptor)

指定したストリームおよびインデックスの種類について、インデックス設定を取得します。

pIndexIdentifierASF_INDEX_IDENTIFIER*inステータスを取得する対象のストリーム番号とインデックスの種類を含む ASF_INDEX_IDENTIFIER 構造体へのポインター。
pfIsIndexedBOOL*outpIndexIdentifier で記述されたインデックスが作成済みかどうかを指定するブール値を取得する変数。
pbIndexDescriptorBYTE*outインデックス記述子を受け取るバッファー。インデックス記述子は、ASF_INDEX_DESCRIPTOR 構造体と、その後に続く任意のインデックス固有データで構成されます。
pcbIndexDescriptorDWORD*inout入力時には、pbIndexDescriptor が指すバッファーのサイズ (バイト単位) を指定します。pbIndexDescriptorNULL の場合、この値は 0 にできます。出力時には、インデックス記述子のサイズ (バイト単位) を受け取ります。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
MF_E_BUFFERTOOSMALL
pcbIndexDescriptor に指定されたバッファーサイズが小さすぎます。

解説(Remarks)

既存の ASF インデックスを読み取るには、このメソッドを呼び出す前に IMFASFIndexer::SetIndexByteStreams を呼び出します。

ストリームのインデックスが存在し、pcbIndexDescriptor に渡された値が pbIndexDescriptor バッファーに必要なサイズより小さい場合、このメソッドは MF_E_BUFFERTOOSMALL を返します。必要なバッファーサイズは pcbIndexDescriptor パラメーターで返されます。

指定したストリームのインデックスが存在しない場合、このメソッドは pfIsIndexed パラメーターに FALSE を返します。

vtbl 10 HRESULT SetIndexStatus(BYTE* pbIndexDescriptor, DWORD cbIndexDescriptor, BOOL fGenerateIndex)

ストリームのインデックスを構成します。

pbIndexDescriptorBYTE*in設定するインデックス記述子。インデックス記述子は、ASF_INDEX_DESCRIPTOR 構造体と、その後に続く任意のインデックス固有データです。
cbIndexDescriptorDWORDinインデックス記述子のサイズ (バイト単位)。
fGenerateIndexBOOLinブール値。インデックス記述子で指定されたストリームに対して、指定した種類のインデックスをインデクサーに作成させるには TRUE に設定します。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
MF_E_INVALIDREQUEST
シーク専用シナリオでインデックスステータスを変更しようとしました。詳細については「解説」を参照してください。

解説(Remarks)

IMFASFIndexer::GenerateIndexEntries を呼び出す前に、SetIndexStatus の呼び出しをすべて行う必要があります。

インデクサーオブジェクトは、既定では各ストリームに対して時間ベースのインデックスを作成するように構成されています。既定の設定を上書きする場合にのみ、このメソッドを呼び出してください。

このメソッドはインデックス読み取りシナリオでは使用できません。インデックスを書き込む場合にのみ使用できます。

vtbl 11 HRESULT GetSeekPositionForValue(PROPVARIANT* pvarValue, ASF_INDEX_IDENTIFIER* pIndexIdentifier, ULONGLONG* pcbOffsetWithinData, LONGLONG* phnsApproxTime, DWORD* pdwPayloadNumberOfStreamWithinPacket)

目的のシーク時刻を指定すると、クライアントがデータの読み取りを開始すべきオフセットを取得します。

pvarValuePROPVARIANT*in位置を取得する対象のインデックスエントリの値。この値の形式は、インデックス識別子で指定されるインデックスの種類によって異なります。時間ベースのインデックスの場合、バリアント型は VT_I8 であり、値は目的のシーク時刻 (100 ナノ秒単位) です。
pIndexIdentifierASF_INDEX_IDENTIFIER*inストリーム番号とインデックスの種類を識別する ASF_INDEX_IDENTIFIER 構造体へのポインター。
pcbOffsetWithinDataULONGLONG*out

ASF Data Object のデータセグメント内のオフセットを受け取ります。オフセットはバイト単位で、パケット 0 の先頭を基準とします。このオフセットは、クライアントがストリームからの読み取りを開始すべき開始位置を示します。この位置は、要求されたシーク時刻に正確に対応しない場合があります。

逆再生の場合、目的のシーク位置より後にキーフレームが存在しないときは、このパラメーターは MFASFINDEXER_READ_FOR_REVERSEPLAYBACK_OUTOFDATASEGMENT の値を受け取ります。その場合、シーク位置はデータセグメントの末尾を 1 バイト超えた位置になります。

phnsApproxTimeLONGLONG*inout

pcbOffsetWithinData パラメーターで返されるオフセットに位置するデータの、おおよそのタイムスタンプを受け取ります。この値の精度は ASF インデックスのインデックス化間隔と等しく、通常は約 1 秒です。

  • pIndexIdentifier で指定されたインデックスの種類が GUID_NULL (時間インデックス) の場合、このパラメーターは NULL にできます。
  • その他すべてのインデックスの種類では、このパラメーターは NULL でなければなりません。
おおよそのタイムスタンプを特定できない場合、このパラメーターは MFASFINDEXER_APPROX_SEEK_TIME_UNKNOWN の値を受け取ります。
pdwPayloadNumberOfStreamWithinPacketDWORD*inout指定したストリームの情報を含むペイロードのペイロード番号を受け取ります。パケットには複数のペイロードを含めることができ、それぞれが異なるストリームのデータを含みます。このパラメーターは NULL にできます。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
MF_E_ASF_OUTOFRANGE
要求されたシーク時刻が範囲外です。
MF_E_NO_INDEX
指定したストリームに対して、指定した種類のインデックスが存在しません。
vtbl 12 HRESULT GenerateIndexEntries(IMFSample* pIASFPacketSample)

ファイルの ASF パケットを受け取り、それらに対するインデックスエントリを作成します。

pIASFPacketSampleIMFSample*inASF パケットを含むメディアサンプルの IMFSample インターフェイスへのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
E_INVALIDARG
渡された引数が NULL です。
MF_E_NOT_INITIALIZED
インデクサーが初期化されていません。

解説(Remarks)

ASF インデクサーは、ファイルのインデックスを内部で作成します。インデクサーに送信されたすべてのデータパケットに対する完成したインデックスを取得するには、IMFASFIndexer::CommitIndex でインデックスをコミットし、次に IMFASFIndexer::GetCompletedIndex を呼び出してインデックスエントリをメディアバッファーに書き込みます。インデックスを保持できる十分な大きさのバッファーを割り当てられるようにインデックスのサイズを判断するには、IMFASFIndexer::GetIndexWriteSpace を呼び出します。

このメソッドがインデックスエントリを作成すると、それらは IMFASFIndexer::GetSeekPositionForValue によって直ちに使用可能になります。

pIASFPacketSample で指定するメディアサンプルは、単一の ASF パケットを含むバッファーを保持していなければなりません。IMFASFMultiplexer::GetNextPacket メソッドを呼び出して、ASF マルチプレクサーからサンプルを取得します。

このメソッドはインデックスの読み取り中には使用できず、インデックスの書き込み時にのみ使用できます。

vtbl 13 HRESULT CommitIndex(IMFASFContentInfo* pIContentInfo)

ASF コンテンツに関連付けられた ContentInfo オブジェクトに、新しいインデックスに関する情報を追加します。後でインデクサーがインデックスを読み取れるようにするため、インデックスをコンテンツにコピーする前にこのメソッドを呼び出す必要があります。

pIContentInfoIMFASFContentInfo*inコンテンツを記述する ContentInfo オブジェクトの IMFASFContentInfo インターフェイスへのポインター。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
MF_E_INVALIDREQUEST
呼び出し元が無効な要求を行いました。詳細については「解説」を参照してください。

解説(Remarks)

インデックスが正しく機能するためには、IMFASFIndexer::GenerateIndexEntries メソッドを使用してファイル内のすべての ASF パケットをインデクサーに渡した後に、このメソッドを呼び出す必要があります。このメソッドを呼び出した後は、GetCompletedIndex を呼び出してインデックスを取得し、ファイル内の適切な場所に書き込む必要があります。最後に、ASF ContentInfo オブジェクトの IMFASFContentInfo::GenerateHeader メソッドを呼び出して、新しい ASF ヘッダーを生成する必要があります。

アプリケーションは、新しいインデックスを書き込む場合にのみ CommitIndex メソッドを使用しなければなりません。そうでない場合、CommitIndex は結果として MF_E_INVALIDREQUEST を返すことがあります。たとえば、アプリケーションがインデクサーオブジェクトに MFASF_INDEXER_WRITE_NEW_INDEX 以外のフラグを設定している場合、MF_E_INVALIDREQUEST が返されます。また、以前の CommitIndex 呼び出しでインデックスエントリがすでにコミットされている場合にも、CommitIndexMFASF_INDEXER_WRITE_NEW_INDEX を返すことがあります。

このメソッドはインデックス読み取りシナリオでは使用できません。インデックスを書き込む場合にのみ使用できます。

vtbl 14 HRESULT GetIndexWriteSpace(ULONGLONG* pcbIndexWriteSpace)

完成したインデックスを格納するために必要なバッファーのサイズ (バイト単位) を取得します。

pcbIndexWriteSpaceULONGLONG*outインデックスのサイズ (バイト単位) を受け取ります。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
MF_E_INDEX_NOT_COMMITTED
インデックスがコミットされていません。詳細については「解説」を参照してください。

解説(Remarks)

このメソッドを使用してインデックスのサイズを取得し、それを保持できる十分な大きさのバッファーを割り当てます。

IMFASFIndexer::GetIndexWriteSpace を呼び出す前に、IMFASFIndexer::CommitIndex の呼び出しによってインデックスをコミットする必要があります。GetIndexWriteSpace を呼び出す前にインデックスがコミットされていない場合、結果として MF_E_INDEX_NOT_COMMITTED が返されます。

完成したインデックスをメディアバッファーに書き込むには、IMFASFIndexer::GetCompletedIndex を呼び出します。

このメソッドは読み取りシナリオでは使用できません。インデックスを書き込む場合にのみ使用できます。

vtbl 15 HRESULT GetCompletedIndex(IMFMediaBuffer* pIIndexBuffer, ULONGLONG cbOffsetWithinIndex)

ASF インデクサーオブジェクトから、完成したインデックスを取得します。

pIIndexBufferIMFMediaBuffer*inインデックスデータを受け取るメディアバッファーの IMFMediaBuffer インターフェイスへのポインター。
cbOffsetWithinIndexULONGLONGin取得するデータのオフセット (インデックスデータの先頭からのバイト単位)。最初の呼び出しでは 0 に設定します。以降の呼び出しが必要な場合 (バッファーがインデックス全体を保持できるほど大きくない場合)、最後に取得したバイトの次のバイトに設定します。

戻り値

このメソッドは HRESULT を返します。指定できる値には、次の表に示すものが含まれますが、これらに限定されません。

戻り値 説明
S_OK
メソッドは成功しました。
MF_E_INDEX_NOT_COMMITTED
完成したインデックスを取得しようとする前に、インデックスがコミットされていませんでした。詳細については「解説」を参照してください。

解説(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 の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
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 指定が可能。