* The media server now clones each buffer area only once - before, you could
only add a very limited amount of buffers part of the frame buffer, for example, as that one is usually a very large area. * This could prevent all sorts of media buffers to be cloned on certain conditions (and could also cause a MediaPlayer fallback to bitmap mode for no apparent reason). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32156 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -182,10 +182,32 @@ BufferManager::Dump()
|
|||||||
area_id
|
area_id
|
||||||
BufferManager::_CloneArea(area_id area)
|
BufferManager::_CloneArea(area_id area)
|
||||||
{
|
{
|
||||||
|
clone_info* info;
|
||||||
|
if (fCloneInfoMap.Get(area, info)) {
|
||||||
|
// we have already cloned this particular area
|
||||||
|
TRACE("BufferManager::_CloneArea() area %ld has already been cloned "
|
||||||
|
"(id %ld)\n", area, info->clone);
|
||||||
|
|
||||||
|
info->ref_count++;
|
||||||
|
return info->clone;
|
||||||
|
}
|
||||||
|
|
||||||
void* address;
|
void* address;
|
||||||
area_id clonedArea = clone_area("media_server cloned buffer", &address,
|
area_id clonedArea = clone_area("media_server cloned buffer", &address,
|
||||||
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
|
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
|
||||||
|
|
||||||
|
TRACE("BufferManager::_CloneArea() cloned area %ld, clone id %ld\n",
|
||||||
|
area, clonedArea);
|
||||||
|
|
||||||
|
if (clonedArea >= 0) {
|
||||||
|
clone_info info;
|
||||||
|
info.clone = clonedArea;
|
||||||
|
info.ref_count = 1;
|
||||||
|
|
||||||
|
fCloneInfoMap.Put(area, info);
|
||||||
|
fSourceInfoMap.Put(clonedArea, area);
|
||||||
|
}
|
||||||
|
|
||||||
return clonedArea;
|
return clonedArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,5 +215,24 @@ BufferManager::_CloneArea(area_id area)
|
|||||||
void
|
void
|
||||||
BufferManager::_ReleaseClonedArea(area_id clone)
|
BufferManager::_ReleaseClonedArea(area_id clone)
|
||||||
{
|
{
|
||||||
delete_area(clone);
|
area_id source = fSourceInfoMap.Get(clone);
|
||||||
|
|
||||||
|
clone_info* info;
|
||||||
|
if (!fCloneInfoMap.Get(source, info)) {
|
||||||
|
ERROR("BufferManager::_ReleaseClonedArea(): could not find clone info "
|
||||||
|
"for id %ld (clone %ld)\n", source, clone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (--info->ref_count == 0) {
|
||||||
|
TRACE("BufferManager::_ReleaseClonedArea(): delete cloned area %ld "
|
||||||
|
"(source %ld)\n", clone, source);
|
||||||
|
|
||||||
|
fSourceInfoMap.Remove(clone);
|
||||||
|
fCloneInfoMap.Remove(source);
|
||||||
|
delete_area(clone);
|
||||||
|
} else {
|
||||||
|
TRACE("BufferManager::_ReleaseClonedArea(): released cloned area %ld "
|
||||||
|
"(source %ld)\n", clone, source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct clone_info {
|
struct clone_info {
|
||||||
area_id source;
|
|
||||||
area_id clone;
|
area_id clone;
|
||||||
vint32 ref_count;
|
vint32 ref_count;
|
||||||
};
|
};
|
||||||
@@ -98,6 +97,7 @@ private:
|
|||||||
|
|
||||||
typedef HashMap<id_hash<media_buffer_id>, buffer_info> BufferInfoMap;
|
typedef HashMap<id_hash<media_buffer_id>, buffer_info> BufferInfoMap;
|
||||||
typedef HashMap<id_hash<area_id>, clone_info> CloneInfoMap;
|
typedef HashMap<id_hash<area_id>, clone_info> CloneInfoMap;
|
||||||
|
typedef HashMap<id_hash<area_id>, area_id> SourceInfoMap;
|
||||||
|
|
||||||
_shared_buffer_list* fSharedBufferList;
|
_shared_buffer_list* fSharedBufferList;
|
||||||
area_id fSharedBufferListID;
|
area_id fSharedBufferListID;
|
||||||
@@ -105,5 +105,6 @@ private:
|
|||||||
BLocker fLocker;
|
BLocker fLocker;
|
||||||
BufferInfoMap fBufferInfoMap;
|
BufferInfoMap fBufferInfoMap;
|
||||||
CloneInfoMap fCloneInfoMap;
|
CloneInfoMap fCloneInfoMap;
|
||||||
|
SourceInfoMap fSourceInfoMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user