Microsoft DirectX 8.0 |
アロケータを実装する抽象基底クラス。アロケータは IMemAllocator インターフェイスを公開する。
宣言 : Amfilter.h
allocator はメモリ バッファを割り当てるオブジェクトである。アロケータは有効なバッファのリストを保持する。クライアント(一般的にはフィルタ)がバッファを要求すると、アロケータはそのリストから 1 つを取得する。そのクライアントはバッファをデータで埋め、そのバッファを他のオブジェクトに渡す場合もある。最終的にそのバッファは解放され、アロケータはフリーなバッファのリストにそれを戻す。
各バッファは media sample を呼び出すオブジェクトによってカプセル化される。メディア サンプルは Component Object Model (COM) フレームワークを使ってポインタをメモリ ブロックにパッケージする 1 つの方法である。メディア サンプルは IMediaSample インターフェイスを公開し、CMediaSample クラスを使って実装される。メディア サンプルは結合されたバッファのポインタを含む、それはIMediaSample::GetPointer を呼び出すことにより結合されている。
通常、アロケータは連続的なメモリ ブロックをアロケートする。次にブロック内のアドレスのポインタを含むメディアサンプルを作成する。次の図はアロケータとメディア サンプルとメモリ ブロックの関係を示す。
アロケータを使うには、次のステップを実行する。
Commit メソッドはバッファのメモリを割り当てる仮想メソッド Alloc を呼び出す。Decommit メソッドはメモリを解放する純粋な仮想メソッド Free を呼び出す。派生クラスはこの 2 つのメソッドをオーバーライドしなければならない。
CMemAllocator 基底クラスは CBaseAllocator から派生する。フィルタ基底クラスは CMemAllocator クラスを使用する。
Protected メンバ変数 | |
---|---|
m_lFree | 有効な(フリーの)メディアサンプルのリストのポインタ。 |
m_hSem | サンプルが有効なときの通知済のセマフォ。 |
m_lWaiting | サンプルを待つスレッドの数。 |
m_lCount | 提供するバッファの数。 |
m_lAllocated | 現在割り当てられているバッファの数。 |
m_lSize | 各バッファのサイズ。 |
m_lAlignment | 各バッファのアラインメント。 |
m_lPrefix | 各バッファの接頭値(prefix) |
m_bChanged | バッファ要求が変更されたかどうかを示すフラグ。 |
m_bCommitted | アロケータにコミットされたかどうかを示すフラグ。 |
m_bDecommitInProgress | コミットされていない操作が進行中かどうかを示すフラグ。 |
m_pNotify | サンプルが解放されたときに呼び出されるコールバック インターフェイスのポインタ。 |
m_fEnableReleaseCallback | 解放コールバックが有効かどうかを示すフラグ。 |
Protected メソッド | |
Alloc | バッファのメモリを割り当てる。 仮想。 |
Public メソッド | |
CBaseAllocator | コンストラクタ メソッド。 |
~CBaseAllocator | デストラクタ メソッド。 |
SetNotify | サンプルが解放されるたびに呼び出されるコールバック メソッドを指定する。 |
GetFreeCount | 使われていないメディア サンプルの数を取得。 |
NotifySample | サンプルを待つスレッドを解放。 |
SetWaiting | 待ち状態のスレッドの数をインクリメント。 |
Pure Virtual メソッド | |
Free | 最後のメディア サンプルが解放された後、デコミット操作の間にバッファ メモリを解放する。 |
IMemAllocator メソッド | |
SetProperties | 割り当てるバッファの数と各バッファのサイズを指定する。 |
GetProperties | アロケータが作成するバッファの数とそのバッファのプロパティを取得。 |
Commit | バッファにメモリを割り当てる。 |
Decommit | バッファをデコミットとする。 |
GetBuffer | バッファを含むメディア サンプルを取得。 |
ReleaseBuffer | フリー メディア サンプルのリストにメディア サンプルを返す。 |
有効な(フリーな)メディア サンプル リストのポインタ。
構文
CSampleList m_lFree;
サンプルが有効なときの通知済のセマフォ。
構文
HANDLE m_hSem;
サンプルを待つスレッドの数。
構文
long m_lWaiting
提供するバッファの数。SetProperties メソッドはこの値を設定する。バッファは Commit メソッドが呼び出されるまで割り当てられない。現在割り当てられているバッファの数は m_lAllocated 数値によって指定される。
構文
long m_lCount;
現在割り当てられているバッファの数。
構文
long m_lAllocated;
各バッファのサイズ。
構文
long m_lSize;
各バッファのアラインメント。各バッファのアドレスは複数のこの値でなければならない。接頭値(prefix)はそのアラインメントの中で計算されなければならない。詳細については、「m_lPrefix」を参照すること。
構文
long m_lAlignment;
バイト単位で示した各バッファの接頭値 (prefix)。この値がゼロでないとき、GetBuffer メソッドによって返る各バッファのポインタはサイズ m_lPrefix の複数バイトのブロックで頭に置かれる。m_lSize メンバ変数には、接頭値は含まれない。
構文
long m_lPrefix;
バッファ要求が変更されたかどうかを示すフラグ。SetProperties メソッドはその値を TRUE に設定する。派生クラスでは、純粋な仮想メソッド Alloc はその値を FALSE に戻す。バッファがいったん割り当てられると、m_bChanged が FALSE の間それれを再割り当てする必要はない。
構文
BOOL m_bChanged;
アロケータがコミットされているかどうかを示すフラグ。
構文
BOOL m_bCommitted;
デコミット操作が行われているかどうかを示すフラグ。Decommit メソッドが呼び出された後、すべてのバッファが解放される前に、この値は TRUE になる。この値が TRUE なら、GetBuffer メソッドは失敗する。また値が TRUE の間アロケータはそれ自身を削除するべきではない。
構文
BOOL m_bDecommitInProgress;
サンプルが解放されたとき呼び出されるコールバックのポインタ。
構文
IMemAllocatorNotifyCallbackTemp *m_pNotify;
解放コールバックが有効かどうかを示すフラグ。このフラグはコンストラクタ メソッドでセットされる。この値が FALSE のとき、 SetNotify メソッドを呼び出すと、(デバッグ ビルドでは) assertion to fire となる。
構文
BOOL m_fEnableReleaseCallback;
バッファのメモリを割り当てる。
構文
virtual HRESULT Alloc(void);
戻り値
次の HRESULT 値の 1 つが返る
S_FALSE バッファ要求は変更されていない。 S_OK バッファ要求は変更された。 VFW_E_SIZENOTSET バッファ要求はセットされていない。
注意
このメソッドは Commit メソッドによって呼び出される。
基底クラスでは、このメソッドはメモリを割り当てない。バッファ要求がセットされていなければエラーを返し、変更されていなければ S_FALSE を返し、要求が変更されていれば S_OK を返す。
派生クラスがこのメソッドをオーバーライドして実際のメモリ割り当てをするべきである。通常は派生クラスは次のようなステップで実行する。
- 基底クラスの実装を呼び出し、メモリを本当に割り当てる必要があるかどうかを決定する。
- メモリを割り当てる。
- Createステップ 2 からメモリのチャンクを含む CMediaSample オブジェクトを作成する。
- 各 CMediaSample オブジェクトをフリー サンプル リスト (m_lFree) に追加する。
この例については、「CMemAllocator::Alloc」を参照すること。
コンストラクタ メソッド。
構文
CBaseAllocator( TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr, BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE );
パラメータ
- pName
- アロケータの名前を含む文字列のポインタ。
- pUnk
- このオブジェクトの所有者のポインタ。オブジェクトが集成されている場合、集成されたオブジェクトの IUnknown インターフェイスのポインタを渡す。それ以外の場合はこのパラメータには NULL を設定する。
- phr
- メソッドの成功や失敗を含む HRESULT 値を受け取る変数のポインタ。
- bEvent
- セマフォを作成したかどうかを示すブール値。TRUE なら、アロケータはサンプルが有効になるたびに通知済のセマフォ (m_hSem) を作成する。実装している派生クラスがセマフォを必要としないなら、この値を FALSE に設定する。
- fEnableReleaseCallback
- 解放コールバック メカニズムが有効かどうかを示すブール値。バッファが解放されたときに呼び出されるコールバック インターフェイスを提供したければ、この値を TRUE に設定する。SetNotify メソッドの呼び出しによってコールバックを指定する。
デストラクタ メソッド
構文
~CBaseAllocator(void);
構文
オブジェクトを消去する前に必ず Decommit メソッドを呼び出すこと。基底クラス デストラクタは Decommit を呼び出すことができない、なぜならそのメソッドは純粋仮想メソッド Free を呼び出すからだ。派生クラスはこのデストラクタをオーバーライドして Decommit を呼び出す。
バッファにメモリを割り当てる。IMemAllocator::Commit メソッドを実装する。
構文
HRESULT Commit(void);
戻り値
HRESULT 値を返す。次の表は、可能な値を示している。
S_OK 成功。 VFW_E_SIZENOTSET バッファ要求は指定されていなかった。
注意
このメソッドを呼び出す前に、SetProperties を呼び出してバッファ要求を指定すること。
このメソッドは仮想メソッド Alloc を呼び出してバッファへのメモリの割り当てを行う。派生クラスは Alloc をオーバーライドすることができる。デコミット操作が行われていると、それはキャンセルされる。
このメソッドは GetBuffer メソッドの前に呼び出されなければならない。
バッファをデコミットにする。IMemAllocator::Decommit メソッドを実装する。
構文
HRESULT Decommit(void);
戻り値
S_OK を返す。
注意
このメソッドを呼び出した後で、GetBuffer メソッドを呼び出すと失敗する。サンプルは解放されて、フリー リストに戻る。最後のサンプルが返ると、割り当てたメモリを解放するため、アロケータは Free メソッドを呼び出す。(基底クラスの場合、Free は純粋な仮想メソッド)。
更に、このメソッドは GetBuffer でブロックされたスレッドを解放する。GetBuffer を呼び出すと失敗する。
最後のメディア サンプルが解放された後、デコミット操作中にバッファ メモリを解放する。
構文
virtual void Free(void) PURE;
注意
Decommit メソッドが呼び出された後で、最後のメディア サンプルが解放されたとき、アロケータはこのメソッドを呼び出す。派生クラスはこのメソッドを実装しなければならない。
バッファを含むメディア サンプルを取得する。IMemAllocator::GetBuffer メソッドを実装する。
構文
HRESULT GetBuffer( IMediaSample **ppBuffer, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime, DWORD dwFlags );
パラメータ
- ppBuffer
- バッファのIMediaSample インターフェイスのポインタを取得する変数のアドレス。
- pStartTime
- サンプルの開始タイムのポインタ。
- pEndTime
- サンプルの終了タイムのポインタ。
- dwFlags
- ゼロあるいは複数のフラグのビットの組み合わせ。基底クラスは次のフラグをサポートする。
- AM_GBF_NOWAIT: バッファが有効になるのを待たない。
戻り値
次の HRESULT 値の 1 つを返す。
S_OK 成功。 VFW_E_NOT_COMMITTED アロケータはコミットではなかった。 VFW_E_TIMEOUT タイム アウト。
注意
呼び出し元が dwFlags で AM_GBF_NOWAIT フラグを指定しなくても、このメソッドは次のサンプルが有効になるまでブロックする。
取得したメディア サンプルは割り当てられたバッファの有効なポインタを持つ。呼び出し元は、タイム スタンプやメディア タイムや同期ポイント プロパティのような、サンプルの他のプロパティを設定する責任を持つ。詳細については、「IMediaSample」を参照すること。
基底クラスでは、pStartTime と pEndTime パラメータは無視される。派生クラスはこれらの値を使うことができる。たとえば、ビデオ レンダラ フィルタのアロケータはこれらの値を使って、Microsoft® DirectDraw® サーフェイス間の切り替えの同期を行う。
メソッドがサンプルを待つ必要があるとき、待ちオブジェクト数 (m_lCount) をインクリメントし、セマフォ (m_hSem) の WaitForSingleObject 関数を呼び出す。サンプルが有効になったとき、アロケータの IBaseAllocator::ReleaseBuffer メソッドを呼び出し、m_lCount によってセマフォ カウントをインクリメント (したがって待ちスレッドを解放) し、 m_lCount をゼロに戻す。
使われていないメディア サンプルの数を取得。
構文
HRESULT GetFreeCount( LONG *plBuffersFree );
パラメータ
- plBuffersFree
- 使われていないサンプルの数を受け取る変数のアドレス。
戻り値
S_OK を返す。
注意
この値はフリー リスト (m_lFree) のサンプルと、削除されなかったサンプルをも含む。
アロケータが作成したバッファの数とバッファ プロパティを取得する。IMemAllocator::GetProperties メソッドを実装。
構文
HRESULT GetProperties( ALLOCATOR_PROPERTIES *pProps );
パラメータ
- pProps
- アロケータ プロパティを受け取る ALLOCATOR_PROPERTIES 構造体のポインタ。
戻り値
S_OK を返す。
サンプルを待っているスレッドを解放する。
構文
void NotifySample(void);
注意
サンプルを待っているスレッドがあるとき、m_lWaiting の値はゼロより大きい。m_lWaiting の値がゼロより大きければ、このメソッドは m_hSem セマフォの ReleaseSemaphore 関数を呼び出し、待っているスレッドをアクティブにする。そしてまた m_lWaiting をゼロにリセットする。
このメソッドは、サンプルがフリー リストに戻ったとき ReleaseBuffer メソッドから呼び出される。またアロケータがデコミットのとき Decommit メソッドから呼び出される。
メディア サンプルをフリー メディア サンプルのリストに戻す。IMemAllocator::ReleaseBuffer を実装する。
構文
HRESULT ReleaseBuffer( IMediaSample *pSample );
パラメータ
- pSample
- メディア サンプル オブジェクトの IMediaSample インターフェイスのポインタ。
戻り値
S_OK を返す。
注意
メディア サンプルの参照カウントがゼロになるとき、サンプルは ReleaseBuffer を自分自身のパラメータとして呼び出す。このメソッドは次の動作をする。
サンプルが解放されるたびに呼び出されるコールバック メソッドを指定する。
構文
HRESULT SetNotify( IMemAllocatorNotifyCallbackTemp *pNotify );
パラメータ
- pNotify
- 呼び出し元に実装された IMemAllocatorNotifyCallbackTemp インターフェイスのポインタ。
戻り値
S_OK を返す。
注意
このメソッドは m_pNotify メンバ変数を pNotify と同じ値にセットし、インターフェイスの参照カウントをインクリメントする。m_pNotify が NULL 以外なら、ReleaseBuffer メソッドは IMemAllocatorNotifyCallbackTemp::NotifyRelease を呼び出す。この呼び出しは任意のコンテキストで使われるので、NotifyRelease メソッドを実装するときは、呼び出しがブロックしないように注意する必要がある。たとえば、あるイベントの設定用にメソッドを制限するとか、他のスレッドへのメッセージの発送に制限する。
割り当てられたバッファの数と各バッファのサイズを指定。IMemAllocator::SetProperties メソッドを実装。
構文
HRESULT SetProperties( ALLOCATOR_PROPERTIES *pRequest, ALLOCATOR_PROPERTIES *pActual );
パラメータ
- pRequest
- バッファ要求を含む ALLOCATOR_PROPERTIES 構造体のポインタ。
- pActual
- 実際のバッファ プロパティを受け取る ALLOCATOR_PROPERTIES 構造体のポインタ。
戻り値
以下のHRESULT の 1 つを返す。
S_OK 成功。 E_POINTER NULL ポインタ値。 VFW_E_ALREADY_COMMITTED フィルタがアクティブな間は、割り当てたメモリは変更できない。 VFW_E_BADALIGN 不適切なアラインメントが指定された。 VFW_E_BUFFERS_OUTSTANDING 1 つあるいはそれ以上のバッファがまだアクティブ。
注意
このメソッドはバッファ要求を指定するが、バッファを割り当てるわけではない。Commit メソッドを呼び出してバッファを割り当てる。
呼び出し元は 2 つの ALLOCATOR_PROPERTIES 構造体を割り当てる。pRequest パラメータは呼び出し元のバッファの数と各バッファのサイズを含むバッファ要求を持つ。このメソッドが返ると、pActual パラメータはアロケータにセットされた実際のバッファ プロパティを持つ。このメソッドは成功すると仮定されている基底クラスでは、実際のプロパティは必ず要求されたプロパティと一致する。派生クラスではこれをオーバーライドする場合もある。
アロケータはコミットであってはならないし、特殊なバッファであってもいけない。基底クラスの場合、アラインメントは1でなければならない。CMemAllocator クラスはこの要求をオーバーライドする。
待ちスレッドの数をインクリメントする。
構文
void SetWaiting(void);
注意
このメソッドは m_lWaiting メンバ変数をインクリメントする。スレッドが CBaseAllocator::GetBuffer メソッドでブロックされていると、アロケータは SetWaiting を呼び出し、次に m_hSem セマフォが通知されるのを待つ。ReleaseBuffer メソッドはセマフォに通知し、m_lWaiting をゼロに戻す。