|
Derived from: none
Declared in: be/media/BufferGroup.h
Library: libmedia.so
Allocation: Constructor only
Summary: more...
A BBufferGroup serves as a repository for BBuffers, and can be used to pass those buffers to another node for its use when sending data. It must also be used by your BBufferProducer to acquire BBuffers to put data that you produce into before you send the buffer on to its destination.
You can create a new BBufferGroup by simply calling:
new BBufferGroup;
If you pass in some arguments describing what sort of buffers you want, and how many of them, the group will even create the BBuffers for you. This is how you'll usually use BBufferGroup, from within your BBufferProducer subclass' constructor so you'll know there are buffers ready and waiting when it's time to start sending data. A possible exception is if your node is a filter that simply processes buffers it receives and passes them along.
A BBufferGroup instance runs a thread that reclaims BBuffers whose Recycle() function has been called. If the group is temporarily out of free buffers, a request for a buffer may block until one is available, or until the request times out, if a timeout is specified when the request is made.
If you're doing video processing, you might want your buffers to be BBitmaps. Here's how you can accomplish this:
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 */
This code takes advantage of the B_BITMAP_IS_AREA flag when creating the bitmap. This forces the bitmap to be in a memory area of its very own, which you can then use when creating the BBuffer.
If you need to do real-time accesses to the BBuffer, you should lock it down. In addition, if you use DMA, you'll need to specify for the buffer to be contiguous (you can do this using the BBitmap constructor, specifying the contiguous flag).
Before deleting any BBitmaps used in this way, be sure the buffer group has been deleted first and (if SetOutputBuffersFor() has been used) all buffers have been reclaimed.
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)The first form of the constructor creates a BBufferGroup with some number of BBuffers already allocated by the group. These buffers will all live within a single Kernel Kit area, allocated by the group. The group tries to allocate an area with properties specified by the placement and lock arguments, large enough to hold numBuffers buffers of the specified size (there may be some padding added).
The second form of the constructor creates a BBufferGroup but doesn't create any buffers for it. You should add BBuffers to the group before trying to use it.
The third form of the constructor creates a BBufferGroup that contains the specified list of buffers. bufferList points to an array of buffer IDs for the buffers to be controlled by the group, and numBuffers is the number of buffers in the list. This version of the constructor isn't one you'll use very often.
Before using any buffers from a new BBufferGroup, call InitCheck() to determine if any errors occurred while creating the group.
~BBufferGroup |
~BBufferGroup() Releases all memory used by the BBufferGroup, including the BBuffers it controls.
Keep in mind that AddBuffer() clones the buffer area. This destructor releases the clones, but it's your application's job to release the original area you added.
Your node needs to delete the buffer group corresponding to any connection that is disconnected or whenever the node is deleted. Until your node does so, the other end of the connection will be blocked waiting for the buffer group to be deleted.
AddBuffer() |
status_t AddBuffer(const buffer_clone_info &info) Given the buffer_clone_info, this function clones the buffer and adds the clone to the BBufferGroup. Normally you'll fill out the buffer_clone_info structure yourself.
Since the buffer is cloned, you'll need to delete the original memory area specified by the buffer_clone_info structure yourself when you're no longer using it; the BBufferGroup won't do it for you.
You shouldn't pass the result of a BBuffer::CloneInfo() call to this function, as doing so would create an "alias" buffer for the same memory area. This is probably not the effect you want.
RETURN CODES
- B_OK. No error adding the buffer to the group.
- B_NO_MEMORY. Couldn't clone the buffer into the BBufferGroup's address space.
AddBuffersTo() |
status_t AddBuffersTo(BMessage *message, const char *name,
bool needLock = true)Adds the group's buffers to the specified message, storing them in an array with the specified name. If needLock is true, the BBufferGroup is locked before performing the operation, then unlocked when finished; otherwise, you guarantee that the buffers won't go anywhere during the AddBuffersTo() call.
The buffers are added by ID number, and are therefore in int32 format.
RETURN CODES
- B_OK. No error adding the buffers to the message.
- Errors from AddInt32().
CountBuffers() |
status_t CountBuffers(int32 *outBufferCount) Returns, in outBufferCount, the number of buffers in the group.
RETURN CODES
- B_OK. The number of buffers was returned successfully.
- B_BAD_VALUE. Invalid outBufferCount pointer.
GetBufferList() |
status_t GetBufferList(int32 listCount, BBuffer **outBuffers) Returns a list of all the buffers in the group. When calling GetBufferList(), pass in outBuffers a pointer to an array of BBuffer pointers that you want to be filled with pointers to the group's buffers, and specify the number of elements in the array in listCount.
RETURN CODES
- B_OK. No errors.
- B_BAD_VALUE. listCount is less than 1, or outBuffers is NULL
InitCheck() |
status_t InitCheck(void) Returns the error code resulting from the construction of the BBufferGroup.
RETURN CODES
ReclaimAllBuffers() |
status_t ReclaimAllBuffers(void) If you pass a buffer group to some other BBufferProducer but pass true for willReclaim in the BMediaRoster::SetOutputBuffers() call, you can later reclaim the buffers into the BBufferGroup by calling Reclaim().
ReclaimAllBuffers() will return B_OK when all buffers are accounted for, or return an error if buffers can't be reclaimed.
If you have buffers that reference some object that might go away (such as a BBitmap), you should call ReclaimAllBuffers() on the group and delete the BBufferGroup before that object goes away.
Before reclaiming your buffers, be sure to call BMediaRoster::SetOutputBuffersFor(output, NULL) to let the Media Kit know your producer no longer has permission to use them. If you forget this step, the producer will hang onto the buffers until it's deleted, and your ReclaimAllBuffers() call will hang, possibly forever.
RETURN CODES
- B_OK. All buffers reclaimed successfully.
- B_MEDIA_CANNOT_RECLAIM_BUFFERS. Some buffers couldn't be reclaimed.
RequestBuffer() |
BBuffer *RequestBuffer(size_t size, bigtime_t timeout = B_INFINITE_TIMEOUT) status_t RequestBuffer(BBuffer *outBuffer,
bigtime_t timeout = B_INFINITE_TIMEOUT)Returns a pointer to a BBuffer of at least the specified size that your BBufferProducer subclass can put data into, then pass on to a media_destination. If there isn't a suitable buffer available, the call will block until either a buffer becomes available (in which case the buffer is returned) or the specified timeout is reached.
If you pass a timeout value that's less than zero, RequestBuffer() will return NULL immediately if there's no buffer available, otherwise it will return a pointer to a buffer you can use.
In BeOS Release 4.5, the timeout is ignored (unless you specify a negative value); B_INFINITE_TIMEOUT is always used, regardless of the value you specify.
RequestBuffer() doesn't use the buffer flags; instead, you can look at the buffers within a BBufferGroup to find a specific buffer to request yourself, based on the value returned by BBuffer::Flags() or BBuffer::Size(), for example. Use the second form of RequestBuffer() to obtain a specific buffer.
The first version of RequestBuffer() returns NULL if no buffer can be obtained, and sets errno to the appropriate error code. The second version returns an appropriate error code.
Don't call RequestBuffer() while an outstanding ReclaimAllBuffers() request is pending. To make sure that doesn't happen, a buffer producer should be designed to not know about the old group anymore once SetBufferGroup() is called to change its buffer group.
RETURN CODES
RequestError() |
status_t RequestError(void) Returns the last RequestBuffer() error. This is useful if RequestBuffer() returns NULL.
WaitForBuffers() |
status_t WaitForBuffers(void) Waits until the currently pending buffer reclamation is finished, then returns. If there isn't a buffer reclamation in progress, returns immediately.
RETURN CODES
- B_OK. No error.
- Semaphore errors. Unable to acquire the semaphore used to detect that buffer reclamation is done.
|
Copyright © 2000 Be, Inc. All rights reserved..