/*********************************************************************** * AUTHOR: Marcus Overhagen * FILE: Buffer.cpp * DESCR: ***********************************************************************/ #include #include #include #include "SharedBufferList.h" #include "debug.h" #include "ServerInterface.h" static team_id CurrentTeam(); team_id CurrentTeam() { thread_info info; get_thread_info(find_thread(NULL),&info); return info.team; } /************************************************************* * public struct buffer_clone_info *************************************************************/ buffer_clone_info::buffer_clone_info() { CALLED(); buffer = 0; area = 0; offset = 0; size = 0; flags = 0; } buffer_clone_info::~buffer_clone_info() { CALLED(); } /************************************************************* * public BBuffer *************************************************************/ void * BBuffer::Data() { CALLED(); return fData; } size_t BBuffer::SizeAvailable() { CALLED(); return fSize; } size_t BBuffer::SizeUsed() { CALLED(); return fMediaHeader.size_used; } void BBuffer::SetSizeUsed(size_t size_used) { CALLED(); fMediaHeader.size_used = min_c(size_used,fSize); } uint32 BBuffer::Flags() { CALLED(); return fFlags; } void BBuffer::Recycle() { CALLED(); if (fBufferList == NULL) return; fBufferList->RecycleBuffer(this); } buffer_clone_info BBuffer::CloneInfo() const { CALLED(); buffer_clone_info info; info.buffer = fBufferID; info.area = fArea; info.offset = fOffset; info.size = fSize; info.flags = fFlags; return info; } media_buffer_id BBuffer::ID() { CALLED(); return fBufferID; } media_type BBuffer::Type() { CALLED(); return fMediaHeader.type; } media_header * BBuffer::Header() { CALLED(); return &fMediaHeader; } media_audio_header * BBuffer::AudioHeader() { CALLED(); return &fMediaHeader.u.raw_audio; } media_video_header * BBuffer::VideoHeader() { CALLED(); return &fMediaHeader.u.raw_video; } size_t BBuffer::Size() { CALLED(); return SizeAvailable(); } /************************************************************* * private BBuffer *************************************************************/ /* explicit */ BBuffer::BBuffer(const buffer_clone_info & info) : fBufferList(0), // must be 0 if not correct initialized fData(0), // must be 0 if not correct initialized fSize(0), // should be 0 if not correct initialized fBufferID(0) // must be 0 if not registered { CALLED(); // special case for BSmallBuffer if (info.area == 0 && info.buffer == 0) return; // ask media_server to get the area_id of the shared buffer list area_id id; BMessage request(MEDIA_SERVER_GET_SHARED_BUFFER_AREA); BMessage reply; if (QueryServer(&request, &reply) != B_OK) return; id = reply.FindInt32("area"); fBufferList = _shared_buffer_list::Clone(id); if (fBufferList == NULL) return; BMessage response; BMessage create(MEDIA_SERVER_REGISTER_BUFFER); create.AddInt32("team",CurrentTeam()); create.AddInt32("area",info.area); create.AddInt32("offset",info.offset); create.AddInt32("size",info.size); create.AddInt32("flags",info.flags); create.AddInt32("buffer",info.buffer); // ask media_server to register this buffer, // either identified by "buffer" or by area information. // media_server either has a copy of the area identified // by "buffer", or creates a new area. // the information and the area is cached by the media_server // until the last buffer has been unregistered // the area_id of the cached area is passed back to us, and we clone it. if (QueryServer(&create, &response) != B_OK) return; // the response from media server contains enough information // to clone the memory for this buffer fBufferID = response.FindInt32("buffer"); fSize = response.FindInt32("size"); fFlags = response.FindInt32("flags"); fOffset = response.FindInt32("offset"); id = response.FindInt32("area"); fArea = clone_area("a cloned BBuffer", &fData, B_ANY_ADDRESS,B_READ_AREA | B_WRITE_AREA,id); if (fArea <= B_OK) { TRACE("buffer cloning failed\n"); fData = 0; return; } fData = (char *)fData + fOffset; fMediaHeader.size_used = 0; } BBuffer::~BBuffer() { CALLED(); // unmap the BufferList if (fBufferList != NULL) { fBufferList->Unmap(); } // unmap the Data if (fData != NULL) { BMessage unregister(MEDIA_SERVER_UNREGISTER_BUFFER); BMessage response; unregister.AddInt32("team",(int32)CurrentTeam()); unregister.AddInt32("buffer",fBufferID); // ask media_server to unregister the buffer // when the last clone of this buffer is gone, // media_server will also remove it's cached area QueryServer(&unregister, &response); delete_area(fArea); } } void BBuffer::SetHeader(const media_header *header) { CALLED(); fMediaHeader = *header; fMediaHeader.buffer = fBufferID; } /************************************************************* * public BSmallBuffer *************************************************************/ static const buffer_clone_info info; BSmallBuffer::BSmallBuffer() : BBuffer(info) { UNIMPLEMENTED(); debugger("BSmallBuffer::BSmallBuffer called\n"); } size_t BSmallBuffer::SmallBufferSizeLimit() { CALLED(); return 64; }