xref: /haiku/src/kits/media/BufferCache.cpp (revision 9c9a810c4152ec6acf3d2720e45f7466c38ef590)
19dec2310SAxel Dörfler /*
2fe08f0b3SRyan Leavengood  * Copyright 2019, Ryan Leavengood.
39dec2310SAxel Dörfler  * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
49dec2310SAxel Dörfler  * Copyright 2002, Marcus Overhagen. All Rights Reserved.
59dec2310SAxel Dörfler  * Distributed under the terms of the MIT License.
69dec2310SAxel Dörfler  */
79dec2310SAxel Dörfler 
89dec2310SAxel Dörfler 
99dec2310SAxel Dörfler //! A cache for BBuffers to be received by BBufferConsumer::BufferReceived().
109dec2310SAxel Dörfler 
119dec2310SAxel Dörfler 
129dec2310SAxel Dörfler #include "BufferCache.h"
139dec2310SAxel Dörfler 
149dec2310SAxel Dörfler #include <Buffer.h>
159dec2310SAxel Dörfler 
16b84955d4SBarrett17 #include "MediaDebug.h"
17*9c9a810cSJérôme Duval #include "MediaMisc.h"
18*9c9a810cSJérôme Duval #include "SharedBufferList.h"
199dec2310SAxel Dörfler 
209dec2310SAxel Dörfler 
219dec2310SAxel Dörfler namespace BPrivate {
229dec2310SAxel Dörfler 
239dec2310SAxel Dörfler 
BufferCache()249dec2310SAxel Dörfler BufferCache::BufferCache()
259dec2310SAxel Dörfler {
269dec2310SAxel Dörfler }
279dec2310SAxel Dörfler 
289dec2310SAxel Dörfler 
~BufferCache()299dec2310SAxel Dörfler BufferCache::~BufferCache()
309dec2310SAxel Dörfler {
31fe08f0b3SRyan Leavengood 	BufferMap::Iterator iterator = fMap.GetIterator();
32fe08f0b3SRyan Leavengood 	while (iterator.HasNext()) {
33fe08f0b3SRyan Leavengood 		BufferMap::Entry entry = iterator.Next();
34fe08f0b3SRyan Leavengood 		delete entry.value.buffer;
359dec2310SAxel Dörfler 	}
369dec2310SAxel Dörfler }
379dec2310SAxel Dörfler 
389dec2310SAxel Dörfler 
399dec2310SAxel Dörfler BBuffer*
GetBuffer(media_buffer_id id,port_id port)40fe08f0b3SRyan Leavengood BufferCache::GetBuffer(media_buffer_id id, port_id port)
419dec2310SAxel Dörfler {
42aa50bf9eSDario Casalinuovo 	if (id <= 0)
43aa50bf9eSDario Casalinuovo 		return NULL;
44aa50bf9eSDario Casalinuovo 
45fe08f0b3SRyan Leavengood 	buffer_cache_entry* existing;
46*9c9a810cSJérôme Duval 	if (fMap.Get(id, existing)) {
47*9c9a810cSJérôme Duval 		existing->buffer->fFlags |= BUFFER_TO_RECLAIM;
48fe08f0b3SRyan Leavengood 		return existing->buffer;
49*9c9a810cSJérôme Duval 	}
509dec2310SAxel Dörfler 
519dec2310SAxel Dörfler 	buffer_clone_info info;
529dec2310SAxel Dörfler 	info.buffer = id;
539dec2310SAxel Dörfler 	BBuffer* buffer = new(std::nothrow) BBuffer(info);
54d98b8c7cSDario Casalinuovo 	if (buffer == NULL || buffer->ID() <= 0
55d98b8c7cSDario Casalinuovo 			|| buffer->Data() == NULL) {
56384ae40aSDario Casalinuovo 		delete buffer;
579dec2310SAxel Dörfler 		return NULL;
58384ae40aSDario Casalinuovo 	}
599dec2310SAxel Dörfler 
60d98b8c7cSDario Casalinuovo 	if (buffer->ID() != id)
61d98b8c7cSDario Casalinuovo 		debugger("BufferCache::GetBuffer: IDs mismatch");
62d98b8c7cSDario Casalinuovo 
63fe08f0b3SRyan Leavengood 	buffer_cache_entry entry;
64fe08f0b3SRyan Leavengood 	entry.buffer = buffer;
65fe08f0b3SRyan Leavengood 	entry.port = port;
66fe08f0b3SRyan Leavengood 	status_t error = fMap.Put(id, entry);
67fe08f0b3SRyan Leavengood 	if (error != B_OK) {
689dec2310SAxel Dörfler 		delete buffer;
699dec2310SAxel Dörfler 		return NULL;
709dec2310SAxel Dörfler 	}
719dec2310SAxel Dörfler 
72*9c9a810cSJérôme Duval 	buffer->fFlags |= BUFFER_TO_RECLAIM;
739dec2310SAxel Dörfler 	return buffer;
749dec2310SAxel Dörfler }
759dec2310SAxel Dörfler 
769dec2310SAxel Dörfler 
77fe08f0b3SRyan Leavengood void
FlushCacheForPort(port_id port)78fe08f0b3SRyan Leavengood BufferCache::FlushCacheForPort(port_id port)
79fe08f0b3SRyan Leavengood {
80fe08f0b3SRyan Leavengood 	BufferMap::Iterator iterator = fMap.GetIterator();
81fe08f0b3SRyan Leavengood 	while (iterator.HasNext()) {
82fe08f0b3SRyan Leavengood 		BufferMap::Entry entry = iterator.Next();
83fe08f0b3SRyan Leavengood 		if (entry.value.port == port) {
84*9c9a810cSJérôme Duval 			BBuffer* buffer = entry.value.buffer;
85*9c9a810cSJérôme Duval 			bool isReclaimed = (buffer->fFlags & BUFFER_TO_RECLAIM) == 0;
86*9c9a810cSJérôme Duval 			if (isReclaimed && buffer->fBufferList != NULL)
87*9c9a810cSJérôme Duval 				isReclaimed = buffer->fBufferList->RemoveBuffer(buffer) == B_OK;
88*9c9a810cSJérôme Duval 
89*9c9a810cSJérôme Duval 			if (isReclaimed)
90*9c9a810cSJérôme Duval 				delete buffer;
91*9c9a810cSJérôme Duval 			else {
92*9c9a810cSJérôme Duval 				// mark the buffer for deletion
93*9c9a810cSJérôme Duval 				buffer->fFlags |= BUFFER_MARKED_FOR_DELETION;
94*9c9a810cSJérôme Duval 			}
95fe08f0b3SRyan Leavengood 			// Then remove it from the map
96fe08f0b3SRyan Leavengood 			fMap.Remove(iterator);
97fe08f0b3SRyan Leavengood 		}
98fe08f0b3SRyan Leavengood 	}
99fe08f0b3SRyan Leavengood }
100fe08f0b3SRyan Leavengood 
101fe08f0b3SRyan Leavengood 
1029dec2310SAxel Dörfler }	// namespace BPrivate
103