103 lines
2.0 KiB
C++
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
|