2003-04-15 03:31:32 +04:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2002, 2003 Marcus Overhagen <Marcus@Overhagen.de>
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
* a copy of this software and associated documentation files or portions
|
|
|
|
* thereof (the "Software"), to deal in the Software without restriction,
|
|
|
|
* including without limitation the rights to use, copy, modify, merge,
|
|
|
|
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
|
|
* and to permit persons to whom the Software is furnished to do so, subject
|
|
|
|
* to the following conditions:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* * Redistributions in binary form must reproduce the above copyright notice
|
|
|
|
* in the binary, as well as this list of conditions and the following
|
|
|
|
* disclaimer in the documentation and/or other materials provided with
|
|
|
|
* the distribution.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* to comply with the license above, do not remove the following line */
|
|
|
|
static char __copyright[] = "Copyright (c) 2002, 2003 Marcus Overhagen <Marcus@Overhagen.de>";
|
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
#include <MediaDefs.h>
|
|
|
|
#include <Buffer.h>
|
|
|
|
#include "SharedBufferList.h"
|
|
|
|
#include "debug.h"
|
2002-12-09 02:53:51 +03:00
|
|
|
#include "DataExchange.h"
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-12-09 02:53:51 +03:00
|
|
|
namespace BPrivate { namespace media {
|
|
|
|
extern team_id team;
|
|
|
|
} } // BPrivate::media
|
|
|
|
using namespace BPrivate::media;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
/*************************************************************
|
|
|
|
* 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();
|
2002-11-24 03:27:09 +03:00
|
|
|
fMediaHeader.size_used = min_c(size_used, fSize);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
2003-06-19 18:53:41 +04:00
|
|
|
return fMediaHeader.buffer;
|
|
|
|
//return fBufferID;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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
|
2002-12-09 02:53:51 +03:00
|
|
|
server_get_shared_buffer_area_request area_request;
|
|
|
|
server_get_shared_buffer_area_reply area_reply;
|
|
|
|
if (QueryServer(SERVER_GET_SHARED_BUFFER_AREA, &area_request, sizeof(area_request), &area_reply, sizeof(area_reply)) != B_OK) {
|
2003-06-19 18:53:41 +04:00
|
|
|
ERROR("BBuffer::BBuffer: SERVER_GET_SHARED_BUFFER_AREA failed\n");
|
2002-07-09 16:24:59 +04:00
|
|
|
return;
|
2002-12-09 02:53:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT(area_reply.area > 0);
|
|
|
|
|
|
|
|
fBufferList = _shared_buffer_list::Clone(area_reply.area);
|
|
|
|
if (fBufferList == NULL) {
|
2003-06-19 18:53:41 +04:00
|
|
|
ERROR("BBuffer::BBuffer: _shared_buffer_list::Clone() failed\n");
|
2002-07-09 16:24:59 +04:00
|
|
|
return;
|
2002-12-09 02:53:51 +03:00
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-12-09 02:53:51 +03:00
|
|
|
server_register_buffer_request request;
|
|
|
|
server_register_buffer_reply reply;
|
|
|
|
|
|
|
|
request.team = team;
|
|
|
|
request.info = info;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
// 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.
|
|
|
|
|
2002-12-09 02:53:51 +03:00
|
|
|
if (QueryServer(SERVER_REGISTER_BUFFER, &request, sizeof(request), &reply, sizeof(reply)) != B_OK) {
|
2003-06-19 18:53:41 +04:00
|
|
|
ERROR("BBuffer::BBuffer: failed to register buffer with media_server\n");
|
2002-07-09 16:24:59 +04:00
|
|
|
return;
|
2002-12-09 02:53:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT(reply.info.buffer > 0);
|
|
|
|
ASSERT(reply.info.area > 0);
|
|
|
|
ASSERT(reply.info.size > 0);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
// the response from media server contains enough information
|
|
|
|
// to clone the memory for this buffer
|
2002-12-09 02:53:51 +03:00
|
|
|
fBufferID = reply.info.buffer;
|
|
|
|
fSize = reply.info.size;
|
|
|
|
fFlags = reply.info.flags;
|
|
|
|
fOffset = reply.info.offset;
|
|
|
|
|
|
|
|
fArea = clone_area("a cloned BBuffer", &fData, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, reply.info.area);
|
2002-07-09 16:24:59 +04:00
|
|
|
if (fArea <= B_OK) {
|
2002-12-09 02:53:51 +03:00
|
|
|
// XXX should unregister buffer here
|
2003-06-19 18:53:41 +04:00
|
|
|
ERROR("BBuffer::BBuffer: buffer cloning failed\n");
|
2002-07-09 16:24:59 +04:00
|
|
|
fData = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
fData = (char *)fData + fOffset;
|
|
|
|
fMediaHeader.size_used = 0;
|
2003-06-19 18:53:41 +04:00
|
|
|
fMediaHeader.buffer = fBufferID;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BBuffer::~BBuffer()
|
|
|
|
{
|
|
|
|
CALLED();
|
|
|
|
// unmap the BufferList
|
|
|
|
if (fBufferList != NULL) {
|
|
|
|
fBufferList->Unmap();
|
|
|
|
}
|
|
|
|
// unmap the Data
|
|
|
|
if (fData != NULL) {
|
2002-12-09 02:53:51 +03:00
|
|
|
|
|
|
|
delete_area(fArea);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
// 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
|
2002-12-09 02:53:51 +03:00
|
|
|
server_unregister_buffer_command cmd;
|
|
|
|
cmd.team = team;
|
|
|
|
cmd.bufferid = fBufferID;
|
|
|
|
SendToServer(SERVER_UNREGISTER_BUFFER, &cmd, sizeof(cmd));
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
BBuffer::SetHeader(const media_header *header)
|
|
|
|
{
|
|
|
|
CALLED();
|
|
|
|
fMediaHeader = *header;
|
2003-06-19 18:53:41 +04:00
|
|
|
// fMediaHeader.buffer = fBufferID;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|