The Media Kit Table of Contents     The Media Kit Index

BBufferGroup

Derived from: none

Declared in: be/media/BufferGroup.h

Library: libmedia.so

Allocation: Constructor only

Summary

 BBufferGroupは、複数のBBufferの貯蔵庫として働き、データを送信する際にはそれらのバッファを他のnodeに渡すために使用することができます。BBufferGroupはまた、バッファがそのdestination(目的地)に送られる前に産生したデータを入れておくBBufferを取得するために、BBufferProducerが使用します。

 単純な呼び出しにより、新しいBBufferGroupを生成することができます :

   new BBufferGroup;

 もし必要なバッファがどういうもので、その数がいくつであるかを記述するいくつかの引数を与えたら、そのグループはまさしくBBufferを生成してくれます。これは、BBufferProducerサブクラスのコンストラクタ中でBBufferGroupを使用する一般的な方法です。あなたは、準備が完了し、データの送信を開始する時を待つばかりのバッファがそこにあることを知るでしょう。例外は、もしnodeが、単に受け取ったバッファを処理して次に渡すだけのフィルタである場合です。

 BBufferGroupのインスタンスは、Recycle()関数が呼び出されたBBufferを再請求するスレッドを動作させます。もしグループが一時的にフリーなバッファを失った場合、バッファへの要求は、バッファが一つ使用できるようになるまで、あるいは要求が生成された際に制限時間が指定されていれば、要求が時間切れになるまでブロックされるでしょう。


Using BBitmaps as Buffers

 もしビデオの処理を行っているなら、バッファをBBitmapにしたいでしょう。ここでは、それをどうやって達成するかを説明します :

   BBufferGroup *my_group = new BBufferGroup;
   BBitmap *my_bitmap = new BBitmap(BRect(0,0,639,479), B_BITMAP_IS_AREA,
               B_RGB32, 640*4);
   
   if (!my_bitmap->IsValid()) {
      return B_ERROR;
   }
   area_info bm_info;
   
   if (get_area_info(my_bitmap->Area(), &bm_info) != B_OK) {
      return B_ERROR;
   }
   
   buffer_clone_info bc_info;
   bc_info.area = bm_info.area;
   bc_info.offset = ((char *) my_bitmap->Bits())-((char *) bm_info.address);
   bc_info.size = my_bitmap->BitsLength();
   
   BBuffer *out_buffer = NULL;
   status_t err = my_group->AddBuffer(bc_info, &out_buffer);
   
   /* out_buffer is now set to use the BBitmap's memory */

 このコードは、ビットマップを生成するときに、B_BITMAP_IS_AREAフラグを設定できる利点があります。これはビットマップに対して、まさにそれ自身のメモリ領域に置かれるように強制します。これ以後、BBufferを作成する際にこれを使用することができます。

 もしBBufferにリアルタイムなアクセスを行う必要があれば、それをロックして下さい。加えて、もしDMAを使用するのであれば、バッファに対して近接(contiguous)するように指定する必要があります(これは、BBitmapコンストラクタのcontiguousフラグで指定できます)。

 
BBitmapをこの方法で削除する前に、必ずバッファグループがまず削除されており、(もしSetOutputBuffersFor()が使用されていれば)全てのバッファが返還要求されていることを確認して下さい。



Constructor and Destructor


BBufferGroup()

                                                         
  

BBufferGroup(size_t size, int32 numBuffers = 3,
      uint32 placement = B_ANY_ADDRESS,
      uint32 lock = B_FULL_LOCK)

BBufferGroup(void)

BBufferGroup(int32 numBuffers, const buffer_id *bufferList)

 コンストラクタの最初の形式では、すでにグループによって領域確保されたBBufferの数を用いてBBufferGroupを生成します。これらのバッファは、グループによって領域確保され、すべて単一のKernel Kit領域に生息しています。グループは、引数 placement及びlockによって指定される属性によって、指定されたsizenumBuffers個のバッファを内包するのに十分な領域を確保しようと試みます(領域には詰め物が追加されるでしょう)。

 コンストラクタの2番目の形式では、BBufferGroupは生成されますが、そのためのバッファは全く生成されません。使用する前に、BBufferをそのグループに追加して下さい。

 コンストラクタの3番目の形式では、指定されたバッファのリストを内包するBBufferGroupが生成されます。bufferListにはグループによって制御されるバッファのバッファIDの配列のポインタが指定され、numBuffersにはリスト中のバッファの数が指定されます。この種類のコンストラクタは、それほど頻繁に使用されるものではありません。

 新しいBBufferGroupからのバッファを使用する前に、グループを作成する際になんらかのエラーが生じていないか確認するためにInitCheck()を呼び出して下さい。


~BBufferGroup

                                                         
  

~BBufferGroup()

 それが制御するBBufferも含め、BBufferGroupによって使用される全てのメモリを解放します。

 AddBuffer()がバッファ領域を複製するということを覚えておいて下さい。このデストラクタは複製を解放しますが、あなたが追加したオリジナルの領域を解放するのはあなたのアプリケーションの仕事です。

 
nodeは、接続が切断されるかそのnodeが削除される時には必ず、それに対応するバッファグループを削除する必要があります。nodeがそれを行うまで、他の接続の終端はバッファグループが削除されるのを待つためにブロックされるでしょう。



Member Functions


AddBuffer()

                                                         
  

status_t AddBuffer(const buffer_clone_info &info)

 buffer_clone_infoを与えることで、この関数はバッファを複製し、その複製をBBufferGroupに追加します。普段は、あなた自身がbuffer_clone_info構造体を構築して下さい。

 このバッファは複製であることから、それを使用しなくなった時、buffer_clone_info構造体で指定されるメモリ領域をあなたの手で削除する必要があります。BBufferGroupは、それを行ってはくれません。

 
この関数に、BBuffer::CloneInfo()呼び出しの結果を渡さないで下さい。それをすると、同じメモリ領域に対して「エリアス」が作成されます。これはおそらく、あなたの望まない結果になります。


RETURN CODES

B_OK. バッファをグループに追加する際にエラーが生じなかった。


AddBuffersTo()

                                                         
  

status_t AddBuffersTo(BMessage *message, const char *name,
      bool needLock = true)

 グループのバッファを指定されたmessageに追加し、指定されたnameの配列にそれらを保存します。もしneedLocktrueなら、BBufferGroupは処理を行う前にロックされ、それが完了したらロックを解除されます。そうでなければ、AddBuffersTo()が呼び出されている間にバッファがどこかに行ってしまわないように保証する必要があります。

 バッファはID番号によって追加されます。番号はint32のフォーマットです。

RETURN CODES

B_OK. メッセージにバッファを追加する際にエラーは生じなかった。


CountBuffers()

                                                         
  

status_t CountBuffers(int32 *outBufferCount)

 outBufferCountに、グループのバッファの数を返します。

RETURN CODES

B_OK. バッファ数は問題なく返された。


GetBufferList()

                                                         
  

status_t GetBufferList(int32 listCount, BBuffer **outBuffers)

 グループ内の全てのバッファのリストを返します。GetBufferList()を呼び出す時、outBuffersにグループのバッファへのポインタを収めたいBBufferポインタの配列へのポインタを渡して下さい。そしてlistCountに配列の要素の数を指定して下さい。

RETURN CODES

B_OK. エラーなし。


InitCheck()

                                                         
  

status_t InitCheck(void)

 BBufferGroupのコンストラクトの結果のエラーコードを返します。

RETURN CODES

B_OK. 新しいグループが問題なく作成された。


ReclaimAllBuffers()

                                                         
  

status_t ReclaimAllBuffers(void)

 もし他のBBufferProducerにバッファグループを渡しても、BMediaRoster::SetOutputBuffers()呼び出しでwillReclaimtrueを渡したら、後でReclaim()を呼び出せばBBufferGroupにバッファを再請求できます。

 ReclaimAllBuffers()は、全てのバッファを補足できた時はB_OKを返しますが、バッファが再請求できなければエラーを返します。

 もし(BBitmapの様に)消え去ってしまうオブジェクトを参照するバッファがあれば、オブジェクトが消えてしまう前に、グループのReclaimAllBuffers()を呼び出してBBufferGroupを削除して下さい。

 
バッファを再請求する前に、もはやproducerにはそれを使用する許可がないということをMedia Kitに知らせるために、必ずBMediaRoster::SetOutputBuffersFor(output, NULL)を呼び出して下さい。もしこのステップを忘れると、producerはバッファが削除されるまでその上で(もしかしたら永遠に)彷徨うことになります。


RETURN CODES

B_OK. 全てのバッファは問題なく再請求された。


RequestBuffer()

                                                         
  

BBuffer *RequestBuffer(size_t size, bigtime_t timeout = B_INFINITE_TIMEOUT)

status_t RequestBuffer(BBuffer *outBuffer,
      bigtime_t timeout = B_INFINITE_TIMEOUT)

 最低でもBBufferProducerサブクラスがデータを入れることのできる指定されたsizeBBufferへのポインタを返し、その後media_destinationに渡します。もし適切なバッファが使用可能でなければ、この呼び出しはバッファが使用可能になるか(この場合はバッファが返されることによって)、あるいは指定されたtimeoutに到達するまでブロックされるでしょう。

 もし0より小さいtimeout値を渡したら、使用できるバッファがない場合、RequestBuffer()は直ちにNULLを返します。そうでなければ、使用できるバッファへのポインタを返します。

 
BeOS Release 4.5では、(負の値を指定しなければ)timeoutは無視されます。B_INFINITE_TIMEOUTが常に使用され、指定された値には頓着されません。


 RequestBuffer()は、バッファフラグを使用しません。その代わりに、例えばBBuffer::Flags()またはBBuffer::Size()によって返された値を元にして、あなたの要求した特定のバッファを探すために、BBufferGroupの中のバッファを見ることができます。特定のバッファを得るためには、RequestBuffer()の2番目の形式を使用して下さい。

 最初の形式のRequestBuffer()は、もしバッファが得られなければNULLを返し、errno(訳不能)に適切なエラーコードを返します。2番目の形式では、適切なエラーコードが返されます。

 
未解決のReclaimAllBuffers()要求が処理待ちの間は、RequestBuffer()を呼び出さないで下さい。それが決して起こらないようにすることで、buffer producerは、一旦SetBufferGroup()が呼ばれてbuffer groupが変更になったら、古いグループに関しては二度と目を向けないように設計されています。


RETURN CODES

B_OK. エラーなし。


RequestError()

                                                         
  

status_t RequestError(void)

 最後に起こったRequestBuffer()エラーを返します。これはRequestBuffer()NULLを返したときに便利です。


WaitForBuffers()

                                                         
  

status_t WaitForBuffers(void)

 現在処理中のバッファ再請求が終了するまで待ち、その後返ります。もしバッファの再請求が処理中でなければ、直ちに返ります。

RETURN CODES

B_OK. エラーなし。


The Media Kit Table of Contents     The Media Kit Index


The Be Book,
...in lovely HTML...
for BeOS Release 5.

Copyright © 2000 Be, Inc. All rights reserved..