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

IAsyncReader

COM
IID56a868aa-0ad4-11ce-b03a-0020af0ba770継承元IUnknown自前メソッド開始 vtbl3

公式ドキュメント

IAsyncReader インターフェースは、フィルター上で非同期のデータ要求を実行します。このインターフェースは、非同期の読み取り操作を行う出力ピンによって公開されます。

メソッド 8

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

vtbl 3 HRESULT RequestAllocator(IMemAllocator* pPreferred, ALLOCATOR_PROPERTIES* pProps, IMemAllocator** ppActual)

RequestAllocator メソッドは、ピンの接続時にアロケーターを要求します。

pPreferredIMemAllocator*in入力ピンが優先するアロケーターの IMemAllocator インターフェースへのポインター。優先するものがない場合は NULL を指定します。
pPropsALLOCATOR_PROPERTIES*in呼び出し側が確保した ALLOCATOR_PROPERTIES 構造体のアドレスを指定します。呼び出し側は、入力ピンが必要とするアロケーターのプロパティを設定し、残りのメンバーはゼロに設定してください。
ppActualIMemAllocator**outIMemAllocator インターフェースポインターを受け取る変数のアドレス。

戻り値

HRESULT 値を返します。取り得る値には次のものが含まれます。

Return code Description
E_FAIL
アロケーターの初期化に失敗しました。
VFW_E_BADALIGN
無効なアラインメントが指定されました。
S_OK
アロケーターが返されました。

解説(Remarks)

下流の入力ピンは、接続処理の間にこのメソッドを呼び出してください。ピンに優先するアロケーターがある場合は、pPreferred パラメーターで指定します。バッファーサイズやアラインメントなどのバッファー要件は、pProps パラメーターで指定します。出力ピンがアロケーターを選択し、ppActual パラメーターでそのポインターを返します。

出力ピンは、入力ピンの要求に従う義務はありません。入力ピンに絶対的な要件がある場合は、返されたアロケーターに対して IMemAllocator::GetProperties メソッドを呼び出してください。アロケーターのプロパティが適切でない場合は、接続を失敗させることができます。接続が確立された後は、入力ピンは出力ピンが選択したアロケーターを使用しなければなりません。

入力ピンは、アロケーターのコミットおよびデコミットを行う責任があります。

vtbl 4 HRESULT Request(IMediaSample* pSample, UINT_PTR dwUser)

Request メソッドは、データに対する非同期要求をキューに登録します。

pSampleIMediaSample*in呼び出し側が提供するメディアサンプルの IMediaSample インターフェースへのポインター。
dwUserUINT_PTRin要求が完了したときに返される任意の値を指定します。

戻り値

HRESULT 値を返します。取り得る値には次のものが含まれます。

Return code Description
S_OK
成功しました。
VFW_E_BADALIGN
バッファーが正しくアラインメントされていません。
VFW_E_SAMPLE_TIME_NOT_SET
サンプルにタイムスタンプが設定されていません。
VFW_E_WRONG_STATE
ピンがフラッシュ中です。
HRESULT_FROM_WIN32(ERROR_HANDLE_EOF)
要求された開始位置がファイルの末尾を超えています。
E_OUTOFMEMORY
メモリが不足しています。

解説(Remarks)

このメソッドを呼び出す前に、ピンのアロケーターからメディアサンプルを取得してください。要求するバイトオフセット(最初と最後を含む)に 10,000,000 を掛けた値を、サンプルにタイムスタンプとして設定します。バイトオフセットはストリームの先頭を基準とします。

開始位置と終了位置は、ピンの接続時に決定されたアラインメントに一致させる必要があります。そうでない場合、このメソッドは VFW_E_BADALIGN を返すことがあります。合意されたアラインメントがストリームの実際のアラインメントより粗い場合、終了位置が実際の長さを超えることがあります。その場合、メソッドは終了位置を実際のアラインメントに切り下げます。

技術的には COM の規則違反ですが、呼び出し側はサンプルに未解放の参照カウントを残しておく必要があります。Request メソッドは AddRefRelease を呼び出さないため、サンプルを有効な状態に保つにはこの参照カウントが必要です。

このメソッドは要求が完了する前に戻ります。要求を待機するには IAsyncReader::WaitForNext メソッドを呼び出してください。要求が保留されている間は、元のメディアサンプルを再利用しないでください。WaitForNext メソッドは元のサンプルへのポインターを返します。要求が成功した場合、サンプルには要求されたデータが格納されています。WaitForNext メソッドは、dwUser パラメーターで指定された値も返します。呼び出し側はこの値を使ってサンプルを識別できます。

次の例は、要求をキューに登録するための入力ピン用ヘルパー関数の一例を示します。

C++
CMyPin::QueueSample(long cbFirst, long cbLast, DWORD_PTR dwuser)
{
    IMediaSample* pSample = NULL;
    HRESULT hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0);
    if (FAILED(hr)) 
    { 
        return hr; 
    }

    LONGLONG tStart = cbFirst * 10000000, tStop = cbLast * 10000000;
    hr = pSample->SetTime(&tStart, &tStop);
    if (SUCCEEDED(hr))
    {
        hr = m_pReader->Request(pSample, dwuser);
    }

    if (FAILED(hr))
    {
        pSample->Release();
    }
    return hr;
}
vtbl 5 HRESULT WaitForNext(DWORD dwTimeout, IMediaSample** ppSample, UINT_PTR* pdwUser)

WaitForNext メソッドは、次の保留中の読み取り要求が完了するのを待機します。

dwTimeoutDWORDinタイムアウトをミリ秒単位で指定します。無期限に待機する場合は INFINITE を使用します。
ppSampleIMediaSample**outoptionalIMediaSample インターフェースポインターを受け取る変数のアドレス。
pdwUserUINT_PTR*outIAsyncReader::Request メソッドで指定された dwUser パラメーターの値を受け取る変数へのポインター。

戻り値

HRESULT 値を返します。取り得る値には次のものが含まれます。

Return code Description
VFW_E_TIMEOUT
タイムアウトが経過したか、ピンがフラッシュ中です。
VFW_E_WRONG_STATE
ピンがフラッシュ中です。
E_FAIL
読み取りエラーが発生しました。
S_OK
成功しました。
S_FALSE
ファイルの末尾に達しました。要求より少ないバイト数を取得しました。

解説(Remarks)

メソッドが成功した場合、ppSample パラメーターには、要求されたデータをバッファーに保持するメディアサンプルへのポインターが格納されます。IMediaSample::GetTime メソッドを呼び出し、その結果を 10,000,000 で割ることで、開始バイトと終了バイトを求めることができます。サンプルは順不同で返される場合があります。データの処理が完了したら、サンプルを解放してください。

ピンがフラッシュ中の場合、このメソッドは失敗します。ただし、ppSample に空のサンプルを返すことがあります。*ppSample が非 NULL の場合は、そのサンプルを解放して破棄してください。詳細については、IAsyncReader::BeginFlush を参照してください。

読み取りエラーが発生した場合、ソースフィルターはフィルターグラフマネージャーにエラーイベントを送信します。呼び出し側がエラーを通知する必要はありません。

vtbl 6 HRESULT SyncReadAligned(IMediaSample* pSample)

SyncReadAligned メソッドは、同期読み取りを実行します。このメソッドは、要求が完了するまでブロックします。ファイル位置とバッファーアドレスはアラインメントされている必要があります。必要なアラインメントについてはアロケーターのプロパティを確認してください。

pSampleIMediaSample*in呼び出し側が提供するメディアサンプルの IMediaSample インターフェースへのポインター。

戻り値

HRESULT 値を返します。取り得る値には次のものが含まれます。

Return code Description
VFW_E_BADALIGN
無効なアラインメントです。
S_FALSE
要求より少ないバイト数を取得しました。(おそらくファイルの末尾に達しました。)
S_OK
成功しました。

解説(Remarks)

このメソッドを呼び出す前に、ピンのアロケーターからメディアサンプルを取得してください。要求するバイトオフセット(最初と最後を含む)に 10,000,000 を掛けた値を、サンプルにタイムスタンプとして設定します。バイトオフセットはストリームの先頭を基準とします。

開始位置と終了位置は、ピンの接続時に決定されたアラインメントに一致させる必要があります。そうでない場合、このメソッドは VFW_E_BADALIGN を返します。合意されたアラインメントがストリームの実際のアラインメントより粗い場合、終了位置が実際の長さを超えることがあります。その場合、メソッドは終了位置を実際のアラインメントに切り下げます。

このメソッドはバッファリングなしの読み取りを行うため、IAsyncReader::SyncRead メソッドよりも高速な場合があります。

vtbl 7 HRESULT SyncRead(LONGLONG llPosition, INT lLength, BYTE* pBuffer)

SyncRead メソッドは、同期読み取りを実行します。このメソッドは、要求が完了するまでブロックします。ファイル位置とバッファーアドレスはアラインメントされている必要はありません。要求がアラインメントされていない場合、このメソッドはバッファリングありの読み取り操作を行います。

llPositionLONGLONGin読み取りを開始するバイトオフセットを指定します。この値がファイルの末尾を超えている場合、メソッドは失敗します。
lLengthINTin読み取るバイト数を指定します。
pBufferBYTE*outデータを受け取るバッファーへのポインター。

戻り値

HRESULT 値を返します。取り得る値には次のものが含まれます。

Return code Description
S_FALSE
要求より少ないバイト数を取得しました。(おそらくファイルの末尾に達しました。)
S_OK
成功しました。

解説(Remarks)

このメソッドは、フィルターが停止している場合でも動作します。

vtbl 8 HRESULT Length(LONGLONG* pTotal, LONGLONG* pAvailable)

Length メソッドは、ストリームの全長を取得します。

pTotalLONGLONG*outストリームの長さ(バイト単位)を受け取る変数へのポインター。
pAvailableLONGLONG*outストリームのうち現在利用可能な部分の長さ(バイト単位)を受け取る変数へのポインター。

戻り値

HRESULT 値を返します。取り得る値には次のものが含まれます。

Return code Description
S_OK
成功しました。
VFW_S_ESTIMATED
返された値は推定値です。たとえば、ファイルがネットワーク経由で読み取られている場合などです。
E_UNEXPECTED
ファイルが開かれていないか、既に存在しません。

解説(Remarks)

ネットワーク経由で取得されるストリームでは、最初はストリーム全体が利用可能でない場合があります。利用可能な長さを超えた読み取り操作は、その部分のストリームが利用可能になるまで、長時間ブロックすることがあります。

vtbl 9 HRESULT BeginFlush()

BeginFlush メソッドは、フラッシュ操作を開始します。(IAsyncReader.BeginFlush)

戻り値

成功した場合は S_OK を、それ以外の場合は S_FALSE を返します。

解説(Remarks)

このメソッドは、保留中のすべての読み取り要求を中断します。ピンがフラッシュ中の間、IAsyncReader::Request メソッドは失敗し、IAsyncReader::WaitForNext メソッドはすぐに戻ります(戻り値が VFW_E_TIMEOUT になる場合があります)。

下流の入力ピンは、下流のフィルターがフィルターグラフをフラッシュするたびに、このメソッドを呼び出してください。このメソッドを呼び出した後、ppSample パラメーターに NULL が返されるまで WaitForNext メソッドを呼び出し続けて、保留中のサンプルのキューをクリアしてください。エラーコードは無視し、各サンプルを解放します。その後、IAsyncReader::EndFlush メソッドを呼び出して、フラッシュ操作を終了します。

詳細については、Flushing を参照してください。

次の例は、下流の入力ピンがこのメソッドをどのように呼び出すべきかを示します。

C++
m_pReader->BeginFlush(); 
while (1) {
    IMediaSample *pSample;
    DWORD_PTR dwUnused;
    m_pReader->WaitForNext(0, &pSample, &dwUnused);
    if(pSample) { 
        pSample->Release();  
    } 
    else {  // No more samples.
        break;
    }
}
m_pReader->EndFlush();
vtbl 10 HRESULT EndFlush()

EndFlush メソッドは、フラッシュ操作を終了します。(IAsyncReader.EndFlush)

戻り値

成功した場合は S_OK を、それ以外の場合は S_FALSE を返します。

解説(Remarks)

ピンがフラッシュ中の間、IAsyncReader::Request メソッドは失敗し、IAsyncReader::WaitForNext メソッドはすぐに戻ります。フラッシュ操作の終わりに EndFlush メソッドを呼び出して、Request メソッドを再び有効にします。

出典・ライセンス: 上記「公式ドキュメント」の内容は 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_IAsyncReader "{56A868AA-0AD4-11CE-B03A-0020AF0BA770}"
#usecom global IAsyncReader IID_IAsyncReader "{}"
#comfunc global IAsyncReader_RequestAllocator  3 sptr,var,sptr
#comfunc global IAsyncReader_Request           4 sptr,sptr
#comfunc global IAsyncReader_WaitForNext       5 int,sptr,var
#comfunc global IAsyncReader_SyncReadAligned   6 sptr
#comfunc global IAsyncReader_SyncRead          7 int64,int,var
#comfunc global IAsyncReader_Length            8 var,var
#comfunc global IAsyncReader_BeginFlush        9
#comfunc global IAsyncReader_EndFlush          10
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。
; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。
; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。