haiku/src/kits/media/BufferCache.cpp

103 lines
2.0 KiB
C++

/*
* Copyright 2019, Ryan Leavengood.
* Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002, Marcus Overhagen. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
//! A cache for BBuffers to be received by BBufferConsumer::BufferReceived().
#include "BufferCache.h"
#include <Buffer.h>
#include "MediaDebug.h"
#include "MediaMisc.h"
#include "SharedBufferList.h"
namespace BPrivate {
BufferCache::BufferCache()
{
}
BufferCache::~BufferCache()
{
BufferMap::Iterator iterator = fMap.GetIterator();
while (iterator.HasNext()) {
BufferMap::Entry entry = iterator.Next();
delete entry.value.buffer;
}
}
BBuffer*
BufferCache::GetBuffer(media_buffer_id id, port_id port)
{
if (id <= 0)
return NULL;
buffer_cache_entry* existing;
if (fMap.Get(id, existing)) {
existing->buffer->fFlags |= BUFFER_TO_RECLAIM;
return existing->buffer;
}
buffer_clone_info info;
info.buffer = id;
BBuffer* buffer = new(std::nothrow) BBuffer(info);
if (buffer == NULL || buffer->ID() <= 0
|| buffer->Data() == NULL) {
delete buffer;
return NULL;
}
if (buffer->ID() != id)
debugger("BufferCache::GetBuffer: IDs mismatch");
buffer_cache_entry entry;
entry.buffer = buffer;
entry.port = port;
status_t error = fMap.Put(id, entry);
if (error != B_OK) {
delete buffer;
return NULL;
}
buffer->fFlags |= BUFFER_TO_RECLAIM;
return buffer;
}
void
BufferCache::FlushCacheForPort(port_id port)
{
BufferMap::Iterator iterator = fMap.GetIterator();
while (iterator.HasNext()) {
BufferMap::Entry entry = iterator.Next();
if (entry.value.port == port) {
BBuffer* buffer = entry.value.buffer;
bool isReclaimed = (buffer->fFlags & BUFFER_TO_RECLAIM) == 0;
if (isReclaimed && buffer->fBufferList != NULL)
isReclaimed = buffer->fBufferList->RemoveBuffer(buffer) == B_OK;
if (isReclaimed)
delete buffer;
else {
// mark the buffer for deletion
buffer->fFlags |= BUFFER_MARKED_FOR_DELETION;
}
// Then remove it from the map
fMap.Remove(iterator);
}
}
}
} // namespace BPrivate