Sorry for this large commit in advance; it's not really possible to divide this

into smaller parts:

media_addon_server:
* Removed (broken) use of (broken and inefficient) home-brewn Map, and List
  classes. This also fixes a crash on shutdown when used with the malloc_debug
  implementation. It's using stl::vector, and stl::map now instead.

_shared_buffer_list:
* Renamed _shared_buffer_list to SharedBufferList, and put it into the BPrivate
  namespace. Also, made a class out of it.
* Separated shared buffer list creation from cloning.
* Enlarged maximum number of buffers to something that is not that evil, but
  actually uses the space it has (ie. is a useful multiple of
  shared_buffer_info that fills a multiple of B_PAGE_SIZE as much as possible).
* No longer drops into the debugger if the
* The list that is currently used is very inefficient for the features it
  provides though (no change there).

_buffer_id_cache:
* Renamed to BufferCache, and put it into the private namespace
* It now deletes its buffers on deletion; since the BBufferConsumer will be
  gone, too, at this point, there is little chance that there are still buffers
  in use.
* Also, it's now using std::map instead of the (see above) Map class.

BBuffer:
* Got rid of the fBufferID member.

Misc.:
* Got rid of the global "team" variable; the media kit is now using the
  private app kit's current_team() now.
* Added a lot of missing error checks (mostly memory allocations).
* Renamed fields like "flavorid" to flavor_id, renamed "dfi_*" fields to
  something more detailed.
* Moved ServerInterface.h from src/servers/media/ to headers/private/media.
* Notifications.h was not self contained.
* Added missing licenses.
* Lots of cleanups, and coding style fixes.

What this doesn't fix:
* Bug #4954 which started all this (this comes next, though)
* Deinitialization is broken, as the PortPool is uninitialized too early, and
  still used afterwards.
* The strange add-on monitoring code in the media_addon_server


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34500 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-12-05 11:11:28 +00:00
parent 04c71a2f1d
commit 9dec231042
31 changed files with 1767 additions and 1548 deletions
+8 -6
View File
@@ -9,7 +9,10 @@
#include <MediaDefs.h> #include <MediaDefs.h>
struct _shared_buffer_list; namespace BPrivate {
class BufferCache;
class SharedBufferList;
}
struct buffer_clone_info { struct buffer_clone_info {
@@ -54,8 +57,8 @@ public:
size_t Size(); size_t Size();
private: private:
friend struct _buffer_id_cache; friend class BPrivate::BufferCache;
friend struct _shared_buffer_list; friend class BPrivate::SharedBufferList;
friend class BMediaRoster; friend class BMediaRoster;
friend class BBufferProducer; friend class BBufferProducer;
friend class BBufferConsumer; friend class BBufferConsumer;
@@ -73,15 +76,14 @@ private:
void SetHeader(const media_header* header); void SetHeader(const media_header* header);
media_header fMediaHeader; media_header fMediaHeader;
_shared_buffer_list* fBufferList; BPrivate::SharedBufferList* fBufferList;
area_id fArea; area_id fArea;
void* fData; void* fData;
size_t fOffset; size_t fOffset;
size_t fSize; size_t fSize;
media_buffer_id fBufferID;
int32 fFlags; int32 fFlags;
uint32 _reserved[11]; uint32 _reserved[12];
}; };
+2 -2
View File
@@ -13,9 +13,9 @@
class BBuffer; class BBuffer;
class BBufferGroup; class BBufferGroup;
class BRegion; class BRegion;
class _buffer_id_cache;
namespace BPrivate { namespace BPrivate {
class BufferCache;
namespace media { namespace media {
class BMediaRosterEx; class BMediaRosterEx;
} }
@@ -147,7 +147,7 @@ private:
private: private:
media_type fConsumerType; media_type fConsumerType;
_buffer_id_cache* fBufferCache; BPrivate::BufferCache* fBufferCache;
BBufferGroup* fDeleteBufferGroup; BBufferGroup* fDeleteBufferGroup;
uint32 _reserved[14]; uint32 _reserved[14];
}; };
+5 -3
View File
@@ -10,7 +10,9 @@
class BBuffer; class BBuffer;
struct _shared_buffer_list; namespace BPrivate {
struct SharedBufferList;
}
class BBufferGroup { class BBufferGroup {
@@ -53,12 +55,12 @@ private:
status_t _Init(); status_t _Init();
private: private:
friend struct _shared_buffer_list; friend struct BPrivate::SharedBufferList;
status_t fInitError; status_t fInitError;
status_t fRequestError; status_t fRequestError;
int32 fBufferCount; int32 fBufferCount;
_shared_buffer_list* fBufferList; BPrivate::SharedBufferList* fBufferList;
sem_id fReclaimSem; sem_id fReclaimSem;
uint32 _reserved[9]; uint32 _reserved[9];
+15 -15
View File
@@ -286,8 +286,8 @@ enum {
}; };
struct addonserver_instantiate_dormant_node_request : request_data { struct addonserver_instantiate_dormant_node_request : request_data {
media_addon_id addonid; media_addon_id addon_id;
int32 flavorid; int32 flavor_id;
team_id creator_team; team_id creator_team;
}; };
@@ -605,8 +605,8 @@ struct server_set_node_creator_reply : reply_data {
}; };
struct server_change_addon_flavor_instances_count_request : request_data { struct server_change_addon_flavor_instances_count_request : request_data {
media_addon_id addonid; media_addon_id addon_id;
int32 flavorid; int32 flavor_id;
int32 delta; // must be +1 or -1 int32 delta; // must be +1 or -1
team_id team; team_id team;
}; };
@@ -624,17 +624,17 @@ struct server_register_node_request : request_data {
}; };
struct server_register_node_reply : reply_data { struct server_register_node_reply : reply_data {
media_node_id nodeid; media_node_id node_id;
}; };
struct server_unregister_node_request : request_data { struct server_unregister_node_request : request_data {
media_node_id nodeid; media_node_id node_id;
team_id team; team_id team;
}; };
struct server_unregister_node_reply : reply_data { struct server_unregister_node_reply : reply_data {
media_addon_id addonid; media_addon_id addon_id;
int32 flavorid; int32 flavor_id;
}; };
struct server_get_live_node_info_request : request_data { struct server_get_live_node_info_request : request_data {
@@ -669,11 +669,11 @@ struct server_node_id_for_request : request_data {
}; };
struct server_node_id_for_reply : reply_data { struct server_node_id_for_reply : reply_data {
media_node_id nodeid; media_node_id node_id;
}; };
struct server_get_node_for_request : request_data { struct server_get_node_for_request : request_data {
media_node_id nodeid; media_node_id node_id;
team_id team; team_id team;
}; };
@@ -713,7 +713,7 @@ struct server_rescan_defaults_command : command_data {
}; };
struct addonserver_rescan_mediaaddon_flavors_command : command_data { struct addonserver_rescan_mediaaddon_flavors_command : command_data {
media_addon_id addonid; media_addon_id addon_id;
}; };
struct addonserver_rescan_finished_notify_command : command_data { struct addonserver_rescan_finished_notify_command : command_data {
@@ -724,15 +724,15 @@ struct server_register_mediaaddon_request : request_data {
}; };
struct server_register_mediaaddon_reply : reply_data { struct server_register_mediaaddon_reply : reply_data {
media_addon_id addonid; media_addon_id addon_id;
}; };
struct server_unregister_mediaaddon_command : command_data { struct server_unregister_mediaaddon_command : command_data {
media_addon_id addonid; media_addon_id addon_id;
}; };
struct server_get_mediaaddon_ref_request : request_data { struct server_get_mediaaddon_ref_request : request_data {
media_addon_id addonid; media_addon_id addon_id;
}; };
struct server_get_mediaaddon_ref_reply : reply_data { struct server_get_mediaaddon_ref_reply : reply_data {
@@ -757,7 +757,7 @@ struct server_register_buffer_reply : reply_data {
struct server_unregister_buffer_command : command_data { struct server_unregister_buffer_command : command_data {
team_id team; team_id team;
media_buffer_id bufferid; media_buffer_id buffer_id;
}; };
struct server_rewindtypes_request : request_data { struct server_rewindtypes_request : request_data {
+4 -1
View File
@@ -2,10 +2,13 @@
* Copyright 2002, Marcus Overhagen. All rights reserved. * Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _NOTIFICATIONS_H #ifndef _NOTIFICATIONS_H
#define _NOTIFICATIONS_H #define _NOTIFICATIONS_H
#include <MediaNode.h>
namespace BPrivate { namespace BPrivate {
namespace media { namespace media {
namespace notifications { namespace notifications {
+9 -11
View File
@@ -1,30 +1,28 @@
/*********************************************************************** /*
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved. * Copyright 2002, Marcus Overhagen. All Rights Reserved.
* This file may be used under the terms of the OpenBeOS License. * Distributed under the terms of the MIT License.
* */
* A pool of kernel ports
***********************************************************************/
#ifndef _POOL_PORT_H_ #ifndef _POOL_PORT_H_
#define _POOL_PORT_H_ #define _POOL_PORT_H_
class PortPool
{ class PortPool {
public: public:
PortPool(); PortPool();
~PortPool(); ~PortPool();
port_id GetPort(); port_id GetPort();
void PutPort(port_id port); void PutPort(port_id port);
private: private:
void Lock(); void Lock();
void Unlock(); void Unlock();
struct PortInfo struct PortInfo {
{
port_id port; port_id port;
bool used; bool used;
}; };
PortInfo * pool; PortInfo * pool;
int count; int count;
int maxcount; int maxcount;
+72
View File
@@ -0,0 +1,72 @@
/*
* Copyright 2002, Marcus Overhagen. All Rights Reserved.
* Copyright 2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _SERVER_INTERFACE_H_
#define _SERVER_INTERFACE_H_
#include <Entry.h>
#include <MediaDefs.h>
#include <MediaNode.h>
#include <MediaAddOn.h>
enum {
ADDONSERVER_INSTANTIATE_DORMANT_NODE,
SERVER_REGISTER_MEDIAADDON,
SERVER_UNREGISTER_MEDIAADDON,
SERVER_GET_MEDIAADDON_REF,
SERVER_REGISTER_DORMANT_NODE,
SERVER_GET_DORMANT_NODES,
SERVER_GET_DORMANT_FLAVOR_INFO,
END
};
struct xfer_server_get_dormant_flavor_info {
media_addon_id addon;
int32 flavor_id;
port_id reply_port;
};
struct xfer_server_get_dormant_flavor_info_reply {
status_t result;
type_code type; // the flatten type_code
size_t flattened_size;
char flattened_data[1];
// a flattened dormant_flavor_info, flattened_size large
};
struct xfer_server_get_dormant_nodes {
int32 max_count;
bool has_input;
media_format input_format;
bool has_output;
media_format output_format;
bool has_name;
char name[B_MEDIA_NAME_LENGTH + 1]; // 1 for a trailing "*"
uint64 require_kinds;
uint64 deny_kinds;
port_id reply_port;
};
struct xfer_server_get_dormant_nodes_reply {
status_t result;
int32 count;
// if count > 0, a second reply containing count dormant_node_infos
// is send
};
struct xfer_server_register_dormant_node {
media_addon_id purge_id;
// if > 0, server must first remove all dormant_flavor_infos
// belonging to that id
type_code type; // the flatten type_code
size_t flattened_size;
char flattened_data[1];
// a flattened dormant_flavor_info, flattened_size large
};
#endif // _SERVER_INTERFACE_H_
+54 -41
View File
@@ -1,53 +1,66 @@
/*********************************************************************** /*
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved. * Copyright 2009, Axel Dörfler, [email protected].
* This file may be used under the terms of the OpenBeOS License. * Copyright 2002, Marcus Overhagen. All Rights Reserved.
* * Distributed under the terms of the MIT License.
* Used for BBufferGroup and BBuffer management across teams */
***********************************************************************/
#ifndef _SHARED_BUFFER_LIST_H_ #ifndef _SHARED_BUFFER_LIST_H_
#define _SHARED_BUFFER_LIST_H_ #define _SHARED_BUFFER_LIST_H_
#include <Buffer.h> #include <Buffer.h>
// created in the media server, cloned into
// each BBufferGroup (visible in all address spaces / teams) namespace BPrivate {
struct _shared_buffer_list
{
struct _shared_buffer_info class SharedBufferList {
{ public:
media_buffer_id id; static area_id Create(SharedBufferList** _list);
BBuffer * buffer; static SharedBufferList* Get(area_id area);
bool reclaimed;
// the reclaim_sem belonging to the BBufferGroup of this BBuffer void Put();
// also used as a unique identifier of the group void DeleteGroupAndPut(sem_id groupReclaimSem);
sem_id reclaim_sem;
status_t Lock();
status_t Unlock();
status_t AddBuffer(sem_id groupReclaimSem,
BBuffer* buffer);
status_t RequestBuffer(sem_id groupReclaimSem,
int32 buffersInGroup, size_t size,
media_buffer_id wantID, BBuffer** _buffer,
bigtime_t timeout);
status_t RecycleBuffer(BBuffer* buffer);
status_t GetBufferList(sem_id groupReclaimSem,
int32 bufferCount, BBuffer** buffers);
private:
struct _shared_buffer_info {
media_buffer_id id;
BBuffer* buffer;
bool reclaimed;
// The reclaim_sem belonging to the BBufferGroup of this BBuffer
// is also used as a unique identifier of the group
sem_id reclaim_sem;
}; };
enum { MAX_BUFFER = 666 }; // this fixed limit is probably very evil
sem_id locker_sem; enum { kMaxBuffers = 2047 };
int32 locker_atom; // 16 bytes per buffer, 8 pages in total (one entry less for the list)
// always only the first "buffercount" entries in the "info" array are used status_t _Init();
int32 buffercount; void _RequestBufferInOtherGroups(
_shared_buffer_info info[MAX_BUFFER]; sem_id groupReclaimSem, media_buffer_id id);
status_t AddBuffer(sem_id group_reclaim_sem, BBuffer *buffer); private:
status_t RequestBuffer(sem_id group_reclaim_sem, int32 buffers_in_group, size_t size, media_buffer_id wantID, BBuffer **buffer, bigtime_t timeout); sem_id fSemaphore;
status_t GetBufferList(sem_id group_reclaim_sem, int32 buf_count, BBuffer **out_buffers); vint32 fAtom;
status_t RecycleBuffer(BBuffer *buffer);
_shared_buffer_info fInfos[kMaxBuffers];
status_t Init(); int32 fCount;
static _shared_buffer_list *Clone(area_id id = -1);
void Terminate(sem_id group_reclaim_sem);
void Unmap();
status_t Lock();
status_t Unlock();
// used by RequestBuffer, call this one with the list locked!
void RequestBufferInOtherGroups(sem_id group_reclaim_sem, media_buffer_id id);
}; };
#endif
} // namespace BPrivate
#endif // _SHARED_BUFFER_LIST_H_
+36 -35
View File
@@ -1,3 +1,8 @@
/*
* Copyright 2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
/* /*
* Copyright (c) 2002, 2003 Marcus Overhagen <[email protected]> * Copyright (c) 2002, 2003 Marcus Overhagen <[email protected]>
* *
@@ -24,12 +29,12 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
*/ */
#include <Buffer.h> #include <Buffer.h>
#include <AppMisc.h>
#include <MediaDefs.h> #include <MediaDefs.h>
#include "debug.h" #include "debug.h"
@@ -37,9 +42,6 @@
#include "SharedBufferList.h" #include "SharedBufferList.h"
namespace BPrivate { namespace media {
extern team_id team;
} }
using namespace BPrivate::media; using namespace BPrivate::media;
@@ -49,11 +51,11 @@ using namespace BPrivate::media;
buffer_clone_info::buffer_clone_info() buffer_clone_info::buffer_clone_info()
{ {
CALLED(); CALLED();
buffer = 0; buffer = 0;
area = 0; area = 0;
offset = 0; offset = 0;
size = 0; size = 0;
flags = 0; flags = 0;
} }
@@ -122,11 +124,11 @@ BBuffer::CloneInfo() const
CALLED(); CALLED();
buffer_clone_info info; buffer_clone_info info;
info.buffer = fBufferID; info.buffer = fMediaHeader.buffer;
info.area = fArea; info.area = fArea;
info.offset = fOffset; info.offset = fOffset;
info.size = fSize; info.size = fSize;
info.flags = fFlags; info.flags = fFlags;
return info; return info;
} }
@@ -137,7 +139,6 @@ BBuffer::ID()
{ {
CALLED(); CALLED();
return fMediaHeader.buffer; return fMediaHeader.buffer;
//return fBufferID;
} }
@@ -181,20 +182,21 @@ BBuffer::Size()
} }
// #pragma mark - private BBuffer // #pragma mark - private BBuffer
BBuffer::BBuffer(const buffer_clone_info& info) BBuffer::BBuffer(const buffer_clone_info& info)
: :
// must all be NULL/0 if not correct initialized // must all be NULL/0 if not correctly initialized
fBufferList(NULL), fBufferList(NULL),
fData(NULL), fData(NULL),
fSize(0), fSize(0)
fBufferID(0)
// must be 0 if not registered
{ {
CALLED(); CALLED();
fMediaHeader.buffer = 0;
// must be 0 if not registered
// special case for BSmallBuffer // special case for BSmallBuffer
if (info.area == 0 && info.buffer == 0) if (info.area == 0 && info.buffer == 0)
return; return;
@@ -208,7 +210,7 @@ BBuffer::BBuffer(const buffer_clone_info& info)
return; return;
} }
fBufferList = _shared_buffer_list::Clone(areaReply.area); fBufferList = BPrivate::SharedBufferList::Get(areaReply.area);
if (fBufferList == NULL) { if (fBufferList == NULL) {
ERROR("BBuffer::BBuffer: _shared_buffer_list::Clone() failed\n"); ERROR("BBuffer::BBuffer: _shared_buffer_list::Clone() failed\n");
return; return;
@@ -217,7 +219,7 @@ BBuffer::BBuffer(const buffer_clone_info& info)
server_register_buffer_request request; server_register_buffer_request request;
server_register_buffer_reply reply; server_register_buffer_reply reply;
request.team = team; request.team = BPrivate::current_team();
request.info = info; request.info = info;
// ask media_server to register this buffer, // ask media_server to register this buffer,
@@ -241,10 +243,11 @@ BBuffer::BBuffer(const buffer_clone_info& info)
// the response from media server contains enough information // the response from media server contains enough information
// to clone the memory for this buffer // to clone the memory for this buffer
fBufferID = reply.info.buffer;
fSize = reply.info.size; fSize = reply.info.size;
fFlags = reply.info.flags; fFlags = reply.info.flags;
fOffset = reply.info.offset; fOffset = reply.info.offset;
fMediaHeader.size_used = 0;
fMediaHeader.buffer = reply.info.buffer;
fArea = clone_area("a cloned BBuffer", &fData, B_ANY_ADDRESS, fArea = clone_area("a cloned BBuffer", &fData, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, reply.info.area); B_READ_AREA | B_WRITE_AREA, reply.info.area);
@@ -256,28 +259,26 @@ BBuffer::BBuffer(const buffer_clone_info& info)
} }
fData = (char*)fData + fOffset; fData = (char*)fData + fOffset;
fMediaHeader.size_used = 0;
fMediaHeader.buffer = fBufferID;
} }
BBuffer::~BBuffer() BBuffer::~BBuffer()
{ {
CALLED(); CALLED();
// unmap the BufferList // unmap the BufferList
if (fBufferList != NULL) if (fBufferList != NULL)
fBufferList->Unmap(); fBufferList->Put();
// unmap the Data // unmap the Data
if (fData != NULL) { if (fData != NULL) {
delete_area(fArea); delete_area(fArea);
// ask media_server to unregister the buffer // Ask media_server to unregister the buffer when the last clone of
// when the last clone of this buffer is gone, // this buffer is gone, media_server will also remove its cached area.
// media_server will also remove it's cached area
server_unregister_buffer_command cmd; server_unregister_buffer_command cmd;
cmd.team = team; cmd.team = BPrivate::current_team();
cmd.bufferid = fBufferID; cmd.buffer_id = fMediaHeader.buffer;
SendToServer(SERVER_UNREGISTER_BUFFER, &cmd, sizeof(cmd)); SendToServer(SERVER_UNREGISTER_BUFFER, &cmd, sizeof(cmd));
} }
} }
@@ -287,14 +288,14 @@ void
BBuffer::SetHeader(const media_header* header) BBuffer::SetHeader(const media_header* header)
{ {
CALLED(); CALLED();
ASSERT(header->buffer == fMediaHeader.buffer);
if (header->buffer != fMediaHeader.buffer)
debugger("oops");
fMediaHeader = *header; fMediaHeader = *header;
// TODO: why can't we do this without crash? what's wrong?
// fMediaHeader.buffer = fBufferID;
} }
// #pragma mark - public BSmallBuffer // #pragma mark - public BSmallBuffer
static const buffer_clone_info sSmallBufferInfo; static const buffer_clone_info sSmallBufferInfo;
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright 2009, Axel Dörfler, [email protected].
* 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 "debug.h"
namespace BPrivate {
BufferCache::BufferCache()
{
}
BufferCache::~BufferCache()
{
for (BufferMap::iterator iterator = fMap.begin(); iterator != fMap.end();
iterator++) {
delete iterator->second;
}
}
BBuffer*
BufferCache::GetBuffer(media_buffer_id id)
{
BufferMap::iterator found = fMap.find(id);
if (found != fMap.end())
return found->second;
buffer_clone_info info;
info.buffer = id;
BBuffer* buffer = new(std::nothrow) BBuffer(info);
if (buffer == NULL)
return NULL;
try {
fMap.insert(std::make_pair(id, buffer));
} catch (std::bad_alloc& exception) {
delete buffer;
return NULL;
}
return buffer;
}
} // namespace BPrivate
+38
View File
@@ -0,0 +1,38 @@
/*
* Copyright 2009, Axel Dörfler, [email protected].
* Copyright 2002, Marcus Overhagen. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _BUFFER_CACHE_H_
#define _BUFFER_CACHE_H_
#include <map>
#include <MediaDefs.h>
class BBuffer;
namespace BPrivate {
class BufferCache {
public:
BufferCache();
~BufferCache();
BBuffer* GetBuffer(media_buffer_id id);
private:
typedef std::map<media_buffer_id, BBuffer*> BufferMap;
BufferMap fMap;
};
} // namespace BPrivate
#endif // _BUFFER_CACHE_H_
+139 -141
View File
@@ -24,37 +24,35 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
*/ */
#include "BufferCache.h"
#include <BufferConsumer.h> #include <BufferConsumer.h>
#include <stdlib.h>
#include <BufferProducer.h> #include <BufferProducer.h>
#include <BufferGroup.h> #include <BufferGroup.h>
#include <Buffer.h> #include <Buffer.h>
#include <TimeSource.h> //for debugging #include <TimeSource.h>
#include <stdlib.h>
#include "debug.h" #include <debug.h>
#include "MediaMisc.h" #include <MediaMisc.h>
#include "DataExchange.h" #include <DataExchange.h>
#include "BufferIdCache.h"
/*************************************************************
* protected BBufferConsumer
*************************************************************/
/* virtual */
BBufferConsumer::~BBufferConsumer() BBufferConsumer::~BBufferConsumer()
{ {
CALLED(); CALLED();
delete fBufferCache; delete fBufferCache;
if (fDeleteBufferGroup) delete fDeleteBufferGroup;
delete fDeleteBufferGroup;
} }
/************************************************************* // #pragma mark - public BBufferConsumer
* public BBufferConsumer
*************************************************************/
media_type media_type
BBufferConsumer::ConsumerType() BBufferConsumer::ConsumerType()
@@ -64,34 +62,31 @@ BBufferConsumer::ConsumerType()
} }
/* static */ status_t /*static*/ status_t
BBufferConsumer::RegionToClipData(const BRegion *region, BBufferConsumer::RegionToClipData(const BRegion* region, int32* _format,
int32 *format, int32 *_size, void* data)
int32 *ioSize,
void *data)
{ {
CALLED(); CALLED();
status_t rv; int count = *_size / sizeof(int16);
int count; status_t status = BBufferProducer::clip_region_to_shorts(region,
static_cast<int16 *>(data), count, &count);
count = *ioSize / sizeof(int16); *_size = count * sizeof(int16);
rv = BBufferProducer::clip_region_to_shorts(region, static_cast<int16 *>(data), count, &count); *_format = BBufferProducer::B_CLIP_SHORT_RUNS;
*ioSize = count * sizeof(int16);
*format = BBufferProducer::B_CLIP_SHORT_RUNS;
return rv; return status;
} }
/*************************************************************
* protected BBufferConsumer
*************************************************************/
/* explicit */ // #pragma mark - protected BBufferConsumer
BBufferConsumer::BBufferConsumer(media_type consumer_type) :
BBufferConsumer::BBufferConsumer(media_type consumerType)
:
BMediaNode("called by BBufferConsumer"), BMediaNode("called by BBufferConsumer"),
fConsumerType(consumer_type), fConsumerType(consumerType),
fBufferCache(new _buffer_id_cache), fBufferCache(new BPrivate::BufferCache),
fDeleteBufferGroup(0) fDeleteBufferGroup(0)
{ {
CALLED(); CALLED();
@@ -100,61 +95,64 @@ BBufferConsumer::BBufferConsumer(media_type consumer_type) :
} }
/* static */ void /*static*/ void
BBufferConsumer::NotifyLateProducer(const media_source &what_source, BBufferConsumer::NotifyLateProducer(const media_source& whatSource,
bigtime_t how_much, bigtime_t howMuch, bigtime_t performanceTime)
bigtime_t performance_time)
{ {
CALLED(); CALLED();
if (IS_INVALID_SOURCE(what_source)) if (IS_INVALID_SOURCE(whatSource))
return; return;
producer_late_notice_received_command command; producer_late_notice_received_command command;
command.source = what_source; command.source = whatSource;
command.how_much = how_much; command.how_much = howMuch;
command.performance_time = performance_time; command.performance_time = performanceTime;
SendToPort(what_source.port, PRODUCER_LATE_NOTICE_RECEIVED, &command, sizeof(command)); SendToPort(whatSource.port, PRODUCER_LATE_NOTICE_RECEIVED, &command,
sizeof(command));
} }
status_t status_t
BBufferConsumer::SetVideoClippingFor(const media_source &output, BBufferConsumer::SetVideoClippingFor(const media_source& output,
const media_destination &destination, const media_destination& destination, const int16* shorts, int32 shortCount,
const int16 *shorts, const media_video_display_info& display, void* userData, int32* _changeTag,
int32 short_count, void *_reserved_)
const media_video_display_info &display,
void *user_data,
int32 *change_tag,
void *_reserved_)
{ {
CALLED(); CALLED();
if (IS_INVALID_SOURCE(output)) if (IS_INVALID_SOURCE(output))
return B_MEDIA_BAD_SOURCE; return B_MEDIA_BAD_SOURCE;
if (IS_INVALID_DESTINATION(destination)) if (IS_INVALID_DESTINATION(destination))
return B_MEDIA_BAD_DESTINATION; return B_MEDIA_BAD_DESTINATION;
if (short_count > int(B_MEDIA_MESSAGE_SIZE - sizeof(producer_video_clipping_changed_command)) / 2) if (shortCount > int(B_MEDIA_MESSAGE_SIZE
debugger("BBufferConsumer::SetVideoClippingFor short_count too large (8000 limit)\n"); - sizeof(producer_video_clipping_changed_command)) / 2) {
debugger("BBufferConsumer::SetVideoClippingFor short_count too large "
"(8000 limit)\n");
}
producer_video_clipping_changed_command *command; producer_video_clipping_changed_command* command;
size_t size; size_t size = sizeof(producer_video_clipping_changed_command)
status_t rv; + shortCount * sizeof(short);
command
= static_cast<producer_video_clipping_changed_command*>(malloc(size));
if (command == NULL)
return B_NO_MEMORY;
size = sizeof(producer_video_clipping_changed_command) + short_count * sizeof(short);
command = static_cast<producer_video_clipping_changed_command *>(malloc(size));
command->source = output; command->source = output;
command->destination = destination; command->destination = destination;
command->display = display; command->display = display;
command->user_data = user_data; command->user_data = userData;
command->change_tag = NewChangeTag(); command->change_tag = NewChangeTag();
command->short_count = short_count; command->short_count = shortCount;
memcpy(command->shorts, shorts, short_count * sizeof(short)); memcpy(command->shorts, shorts, shortCount * sizeof(short));
if (change_tag != NULL) if (_changeTag != NULL)
*change_tag = command->change_tag; *_changeTag = command->change_tag;
status_t status = SendToPort(output.port, PRODUCER_VIDEO_CLIPPING_CHANGED,
command, size);
rv = SendToPort(output.port, PRODUCER_VIDEO_CLIPPING_CHANGED, command, size);
free(command); free(command);
return rv; return status;
} }
@@ -236,9 +234,8 @@ BBufferConsumer::RequestAdditionalBuffer(const media_source &source,
status_t status_t
BBufferConsumer::RequestAdditionalBuffer(const media_source &source, BBufferConsumer::RequestAdditionalBuffer(const media_source& source,
bigtime_t start_time, bigtime_t startTime, void *_reserved)
void *_reserved)
{ {
CALLED(); CALLED();
if (IS_INVALID_SOURCE(source)) if (IS_INVALID_SOURCE(source))
@@ -248,22 +245,18 @@ BBufferConsumer::RequestAdditionalBuffer(const media_source &source,
command.source = source; command.source = source;
command.prev_buffer = 0; command.prev_buffer = 0;
command.prev_time = start_time; command.prev_time = startTime;
command.has_seek_tag = false; command.has_seek_tag = false;
//command.prev_tag =
return SendToPort(source.port, PRODUCER_ADDITIONAL_BUFFER_REQUESTED, &command, sizeof(command)); return SendToPort(source.port, PRODUCER_ADDITIONAL_BUFFER_REQUESTED,
&command, sizeof(command));
} }
status_t status_t
BBufferConsumer::SetOutputBuffersFor(const media_source &source, BBufferConsumer::SetOutputBuffersFor(const media_source &source,
const media_destination &destination, const media_destination &destination, BBufferGroup *group, void *user_data,
BBufferGroup *group, int32 *change_tag, bool will_reclaim, void *_reserved_)
void *user_data,
int32 *change_tag,
bool will_reclaim,
void *_reserved_)
{ {
CALLED(); CALLED();
@@ -323,10 +316,8 @@ BBufferConsumer::SetOutputBuffersFor(const media_source &source,
status_t status_t
BBufferConsumer::SendLatencyChange(const media_source &source, BBufferConsumer::SendLatencyChange(const media_source& source,
const media_destination &destination, const media_destination& destination, bigtime_t newLatency, uint32 flags)
bigtime_t my_new_latency,
uint32 flags)
{ {
CALLED(); CALLED();
if (IS_INVALID_SOURCE(source)) if (IS_INVALID_SOURCE(source))
@@ -338,34 +329,33 @@ BBufferConsumer::SendLatencyChange(const media_source &source,
command.source = source; command.source = source;
command.destination = destination; command.destination = destination;
command.latency = my_new_latency; command.latency = newLatency;
command.flags = flags; command.flags = flags;
TRACE("###### BBufferConsumer::SendLatencyChange: latency from %ld/%ld to %ld/%ld changed to %Ld\n", TRACE("###### BBufferConsumer::SendLatencyChange: latency from %ld/%ld to "
source.port, source.id, destination.port, destination.id, my_new_latency); "%ld/%ld changed to %Ld\n", source.port, source.id, destination.port,
destination.id, newLatency);
return SendToPort(source.port, PRODUCER_LATENCY_CHANGED, &command, sizeof(command)); return SendToPort(source.port, PRODUCER_LATENCY_CHANGED, &command,
sizeof(command));
} }
/*************************************************************
* protected BBufferConsumer
*************************************************************/
/* virtual */ status_t status_t
BBufferConsumer::HandleMessage(int32 message, BBufferConsumer::HandleMessage(int32 message, const void* data, size_t size)
const void *data,
size_t size)
{ {
PRINT(4, "BBufferConsumer::HandleMessage %#lx, node %ld\n", message, ID()); PRINT(4, "BBufferConsumer::HandleMessage %#lx, node %ld\n", message, ID());
status_t rv; status_t rv;
switch (message) { switch (message) {
case CONSUMER_ACCEPT_FORMAT: case CONSUMER_ACCEPT_FORMAT:
{ {
const consumer_accept_format_request *request = static_cast<const consumer_accept_format_request *>(data); const consumer_accept_format_request* request
= static_cast<const consumer_accept_format_request*>(data);
consumer_accept_format_reply reply; consumer_accept_format_reply reply;
reply.format = request->format; reply.format = request->format;
rv = AcceptFormat(request->dest, &reply.format); status_t status = AcceptFormat(request->dest, &reply.format);
request->SendReply(rv, &reply, sizeof(reply)); request->SendReply(status, &reply, sizeof(reply));
return B_OK; return B_OK;
} }
@@ -390,12 +380,17 @@ BBufferConsumer::HandleMessage(int32 message,
case CONSUMER_BUFFER_RECEIVED: case CONSUMER_BUFFER_RECEIVED:
{ {
const consumer_buffer_received_command *command = static_cast<const consumer_buffer_received_command *>(data); const consumer_buffer_received_command* command
BBuffer *buffer; = static_cast<const consumer_buffer_received_command*>(data);
buffer = fBufferCache->GetBuffer(command->buffer);
BBuffer* buffer = fBufferCache->GetBuffer(command->buffer);
buffer->SetHeader(&command->header); buffer->SetHeader(&command->header);
PRINT(4, "calling BBufferConsumer::BufferReceived buffer %ld at perf %Ld and TimeSource()->Now() is %Ld\n", buffer->Header()->buffer, buffer->Header()->start_time, TimeSource()->Now());
//printf("BBufferConsumer::BufferReceived node %2ld, buffer %2ld, start_time %12Ld with lateness %6Ld\n", ID(), buffer->Header()->buffer, buffer->Header()->start_time, TimeSource()->Now() - buffer->Header()->start_time); PRINT(4, "calling BBufferConsumer::BufferReceived buffer %ld at "
"perf %Ld and TimeSource()->Now() is %Ld\n",
buffer->Header()->buffer, buffer->Header()->start_time,
TimeSource()->Now());
BufferReceived(buffer); BufferReceived(buffer);
return B_OK; return B_OK;
} }
@@ -464,8 +459,7 @@ BBufferConsumer::HandleMessage(int32 message,
request->SendReply(rv, &reply, sizeof(reply)); request->SendReply(rv, &reply, sizeof(reply));
return B_OK; return B_OK;
} }
}
};
return B_ERROR; return B_ERROR;
} }
@@ -482,9 +476,9 @@ BBufferConsumer::SeekTagRequested(const media_destination &destination,
return B_ERROR; return B_ERROR;
} }
/*************************************************************
* private BBufferConsumer // #pragma mark - private BBufferConsumer
*************************************************************/
/* /*
not implemented: not implemented:
@@ -493,7 +487,9 @@ BBufferConsumer::BBufferConsumer(const BBufferConsumer &clone)
BBufferConsumer & BBufferConsumer::operator=(const BBufferConsumer &clone) BBufferConsumer & BBufferConsumer::operator=(const BBufferConsumer &clone)
*/ */
/* deprecated function for R4 */
/*! Deprecated function for BeOS R4.
*/
/* static */ status_t /* static */ status_t
BBufferConsumer::SetVideoClippingFor(const media_source &output, BBufferConsumer::SetVideoClippingFor(const media_source &output,
const int16 *shorts, const int16 *shorts,
@@ -529,12 +525,12 @@ BBufferConsumer::SetVideoClippingFor(const media_source &output,
} }
/* deprecated function for R4 */ /*! Deprecated function for BeOS R4.
/* static */ status_t */
BBufferConsumer::RequestFormatChange(const media_source &source, /*static*/ status_t
const media_destination &destination, BBufferConsumer::RequestFormatChange(const media_source& source,
media_format *in_to_format, const media_destination& destination, media_format* format,
int32 *change_tag) int32* _changeTag)
{ {
CALLED(); CALLED();
if (IS_INVALID_SOURCE(source)) if (IS_INVALID_SOURCE(source))
@@ -546,21 +542,22 @@ BBufferConsumer::RequestFormatChange(const media_source &source,
command.source = source; command.source = source;
command.destination = destination; command.destination = destination;
command.format = *in_to_format; command.format = *format;
command.user_data = 0; command.user_data = 0;
command.change_tag = NewChangeTag(); command.change_tag = NewChangeTag();
if (change_tag != NULL) if (_changeTag != NULL)
*change_tag = command.change_tag; *_changeTag = command.change_tag;
return SendToPort(source.port, PRODUCER_FORMAT_CHANGE_REQUESTED, &command, sizeof(command)); return SendToPort(source.port, PRODUCER_FORMAT_CHANGE_REQUESTED, &command,
sizeof(command));
} }
/* deprecated function for R4 */ /*! Deprecated function for BeOS R4.
/* static */ status_t */
BBufferConsumer::SetOutputEnabled(const media_source &source, /*static*/ status_t
bool enabled, BBufferConsumer::SetOutputEnabled(const media_source& source, bool enabled,
int32 *change_tag) int32* _changeTag)
{ {
CALLED(); CALLED();
if (IS_INVALID_SOURCE(source)) if (IS_INVALID_SOURCE(source))
@@ -573,27 +570,28 @@ BBufferConsumer::SetOutputEnabled(const media_source &source,
command.enabled = enabled; command.enabled = enabled;
command.user_data = 0; command.user_data = 0;
command.change_tag = NewChangeTag(); command.change_tag = NewChangeTag();
if (change_tag != NULL) if (_changeTag != NULL)
*change_tag = command.change_tag; *_changeTag = command.change_tag;
return SendToPort(source.port, PRODUCER_ENABLE_OUTPUT, &command, sizeof(command)); return SendToPort(source.port, PRODUCER_ENABLE_OUTPUT, &command,
sizeof(command));
} }
status_t BBufferConsumer::_Reserved_BufferConsumer_0(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_0(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_1(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_1(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_2(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_2(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_3(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_3(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_4(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_4(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_5(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_5(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_6(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_6(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_7(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_7(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_8(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_8(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_9(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_9(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_10(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_10(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_11(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_11(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_12(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_12(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_13(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_13(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_14(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_14(void*) { return B_ERROR; }
status_t BBufferConsumer::_Reserved_BufferConsumer_15(void *) { return B_ERROR; } status_t BBufferConsumer::_Reserved_BufferConsumer_15(void*) { return B_ERROR; }
+4 -4
View File
@@ -127,8 +127,8 @@ BBufferGroup::BBufferGroup(int32 count, const media_buffer_id* buffers)
BBufferGroup::~BBufferGroup() BBufferGroup::~BBufferGroup()
{ {
CALLED(); CALLED();
if (fBufferList) if (fBufferList != NULL)
fBufferList->Terminate(fReclaimSem); fBufferList->DeleteGroupAndPut(fReclaimSem);
delete_sem(fReclaimSem); delete_sem(fReclaimSem);
} }
@@ -404,9 +404,9 @@ BBufferGroup::_Init()
return fInitError; return fInitError;
} }
fBufferList = _shared_buffer_list::Clone(areaReply.area); fBufferList = BPrivate::SharedBufferList::Get(areaReply.area);
if (fBufferList == NULL) { if (fBufferList == NULL) {
ERROR("BBufferGroup::InitBufferGroup: _shared_buffer_list::Clone " ERROR("BBufferGroup::InitBufferGroup: SharedBufferList::Get() "
"failed\n"); "failed\n");
fInitError = B_ERROR; fInitError = B_ERROR;
return fInitError; return fInitError;
-45
View File
@@ -1,45 +0,0 @@
/***********************************************************************
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved.
* This file may be used under the terms of the OpenBeOS License.
*
* A cache for BBuffers to be received by
* BBufferConsumer::BufferReceived()
***********************************************************************/
#include <Buffer.h>
#include "BufferIdCache.h"
#include "debug.h"
// XXX we are not allowed to delete BBuffer objects when they are not recycled
_buffer_id_cache::_buffer_id_cache()
{
}
_buffer_id_cache::~_buffer_id_cache()
{
// XXX deleting buffers here is not save, too
/*
fMap.Rewind();
BBuffer **buffer;
while (fMap.GetNext(&buffer)) {
fMap.RemoveCurrent();
delete *buffer;
}
*/
}
BBuffer *
_buffer_id_cache::GetBuffer(media_buffer_id id)
{
BBuffer **buffer;
if (fMap.Get(id, &buffer))
return *buffer;
buffer_clone_info ci;
ci.buffer = id;
BBuffer *buf = new BBuffer(ci);
fMap.Insert(id, buf);
return buf;
}
-25
View File
@@ -1,25 +0,0 @@
/***********************************************************************
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved.
* This file may be used under the terms of the OpenBeOS License.
*
* A cache for BBuffers to be received by
* BBufferConsumer::BufferReceived()
***********************************************************************/
#ifndef _BUFFER_ID_CACHE_H_
#define _BUFFER_ID_CACHE_H_
#include "TMap.h"
class _buffer_id_cache
{
public:
_buffer_id_cache();
~_buffer_id_cache();
BBuffer *GetBuffer(media_buffer_id id);
private:
Map<media_buffer_id, BBuffer *> fMap;
};
#endif
+39 -28
View File
@@ -3,50 +3,52 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include <OS.h>
#include <Messenger.h> #include <DataExchange.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <Messenger.h>
#include <OS.h>
#include "debug.h" #include "debug.h"
#include "PortPool.h" #include "PortPool.h"
#include "MediaMisc.h" #include "MediaMisc.h"
#include "DataExchange.h"
#include "ServerInterface.h" #include "ServerInterface.h"
#define TIMEOUT 15000000 // 15 seconds timeout! #define TIMEOUT 15000000 // 15 seconds timeout!
namespace BPrivate { namespace BPrivate {
namespace media { namespace media {
team_id team;
namespace dataexchange { namespace dataexchange {
BMessenger *MediaServerMessenger;
BMessenger* MediaServerMessenger;
static port_id MediaServerPort; static port_id MediaServerPort;
static port_id MediaAddonServerPort; static port_id MediaAddonServerPort;
void find_media_server_port(); void find_media_server_port();
void find_media_addon_server_port(); void find_media_addon_server_port();
static BMessenger * GetMediaServerMessenger() { static BMessenger*
static BMessenger * messenger = new BMessenger(B_MEDIA_SERVER_SIGNATURE); GetMediaServerMessenger()
{
static BMessenger* messenger = new BMessenger(B_MEDIA_SERVER_SIGNATURE);
return MediaServerMessenger = messenger; return MediaServerMessenger = messenger;
} }
class initit class initit {
{
public: public:
initit() initit()
{ {
MediaServerMessenger = 0; MediaServerMessenger = 0;
find_media_server_port(); find_media_server_port();
find_media_addon_server_port(); find_media_addon_server_port();
thread_info info;
get_thread_info(find_thread(NULL), &info);
team = info.team;
} }
~initit() ~initit()
{ {
delete MediaServerMessenger; delete MediaServerMessenger;
@@ -55,7 +57,8 @@ public:
initit _initit; initit _initit;
void find_media_server_port() void
find_media_server_port()
{ {
MediaServerPort = find_port(MEDIA_SERVER_PORT_NAME); MediaServerPort = find_port(MEDIA_SERVER_PORT_NAME);
if (MediaServerPort < 0) { if (MediaServerPort < 0) {
@@ -64,7 +67,9 @@ void find_media_server_port()
} }
} }
void find_media_addon_server_port()
void
find_media_addon_server_port()
{ {
MediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME); MediaAddonServerPort = find_port(MEDIA_ADDON_SERVER_PORT_NAME);
if (MediaAddonServerPort < 0) { if (MediaAddonServerPort < 0) {
@@ -84,7 +89,8 @@ request_data::SendReply(status_t result, reply_data *reply, int replysize) const
// BMessage based data exchange with the media_server // BMessage based data exchange with the media_server
status_t SendToServer(BMessage *msg) status_t
SendToServer(BMessage *msg)
{ {
status_t rv; status_t rv;
rv = GetMediaServerMessenger()->SendMessage(msg, static_cast<BHandler *>(NULL), TIMEOUT); rv = GetMediaServerMessenger()->SendMessage(msg, static_cast<BHandler *>(NULL), TIMEOUT);
@@ -110,32 +116,37 @@ QueryServer(BMessage &request, BMessage &reply)
// Raw data based data exchange with the media_server // Raw data based data exchange with the media_server
status_t SendToServer(int32 msgcode, command_data *msg, int size) status_t
SendToServer(int32 msgcode, command_data *msg, int size)
{ {
return SendToPort(MediaServerPort, msgcode, msg, size); return SendToPort(MediaServerPort, msgcode, msg, size);
} }
status_t QueryServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) status_t
QueryServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize)
{ {
return QueryPort(MediaServerPort, msgcode, request, requestsize, reply, replysize); return QueryPort(MediaServerPort, msgcode, request, requestsize, reply, replysize);
} }
// Raw data based data exchange with the media_addon_server // Raw data based data exchange with the media_addon_server
status_t SendToAddonServer(int32 msgcode, command_data *msg, int size) status_t
SendToAddonServer(int32 msgcode, command_data *msg, int size)
{ {
return SendToPort(MediaAddonServerPort, msgcode, msg, size); return SendToPort(MediaAddonServerPort, msgcode, msg, size);
} }
status_t QueryAddonServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) status_t
QueryAddonServer(int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize)
{ {
return QueryPort(MediaAddonServerPort, msgcode, request, requestsize, reply, replysize); return QueryPort(MediaAddonServerPort, msgcode, request, requestsize, reply, replysize);
} }
// Raw data based data exchange with the media_server // Raw data based data exchange with the media_server
status_t SendToPort(port_id sendport, int32 msgcode, command_data *msg, int size) status_t
SendToPort(port_id sendport, int32 msgcode, command_data *msg, int size)
{ {
status_t rv; status_t rv;
@@ -162,7 +173,8 @@ status_t SendToPort(port_id sendport, int32 msgcode, command_data *msg, int size
} }
status_t QueryPort(port_id requestport, int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize) status_t
QueryPort(port_id requestport, int32 msgcode, request_data *request, int requestsize, reply_data *reply, int replysize)
{ {
status_t rv; status_t rv;
int32 code; int32 code;
@@ -202,7 +214,6 @@ status_t QueryPort(port_id requestport, int32 msgcode, request_data *request, in
return (rv < B_OK) ? rv : reply->result; return (rv < B_OK) ? rv : reply->result;
} }
}; // dataexchange } // dataexchange
}; // media } // media
}; // BPrivate } // BPrivate
+5 -4
View File
@@ -232,9 +232,10 @@ DormantNodeManager::RegisterAddon(const char *path)
return 0; return 0;
} }
TRACE("DormantNodeManager::RegisterAddon finished with id %ld\n",reply.addonid); TRACE("DormantNodeManager::RegisterAddon finished with id %ld\n",
reply.addon_id);
return reply.addonid; return reply.addon_id;
} }
// For use by media_addon_server only // For use by media_addon_server only
@@ -250,7 +251,7 @@ DormantNodeManager::UnregisterAddon(media_addon_id id)
port = find_port(MEDIA_SERVER_PORT_NAME); port = find_port(MEDIA_SERVER_PORT_NAME);
if (port <= B_OK) if (port <= B_OK)
return; return;
msg.addonid = id; msg.addon_id = id;
write_port(port, SERVER_UNREGISTER_MEDIAADDON, &msg, sizeof(msg)); write_port(port, SERVER_UNREGISTER_MEDIAADDON, &msg, sizeof(msg));
} }
@@ -267,7 +268,7 @@ DormantNodeManager::FindAddonPath(BPath *path, media_addon_id id)
port = find_port(MEDIA_SERVER_PORT_NAME); port = find_port(MEDIA_SERVER_PORT_NAME);
if (port <= B_OK) if (port <= B_OK)
return B_ERROR; return B_ERROR;
msg.addonid = id; msg.addon_id = id;
msg.reply_port = _PortPool->GetPort(); msg.reply_port = _PortPool->GetPort();
rv = write_port(port, SERVER_GET_MEDIAADDON_REF, &msg, sizeof(msg)); rv = write_port(port, SERVER_GET_MEDIAADDON_REF, &msg, sizeof(msg));
if (rv != B_OK) { if (rv != B_OK) {
+2 -7
View File
@@ -7,17 +7,12 @@ if $(TARGET_PLATFORM) != haiku {
# We need the public media headers also when not compiling for Haiku. # We need the public media headers also when not compiling for Haiku.
} }
UsePrivateHeaders media shared ; UsePrivateHeaders app media shared ;
if $(CHECK_MALLOC) { if $(CHECK_MALLOC) {
SubDirC++Flags -D_NO_INLINE_ASM -fcheck-memory-usage ; SubDirC++Flags -D_NO_INLINE_ASM -fcheck-memory-usage ;
} }
# That's ugly. The header (ServerInterface.h) should reside in
# headers/private/media.
SubDirHdrs [ FDirName $(HAIKU_TOP) src servers media ] ;
SubDirSysHdrs $(SUBDIR) ; # for the Old*.h headers
SharedLibrary libmedia.so : SharedLibrary libmedia.so :
# Private Media Kit # Private Media Kit
!missing_symbols.cpp !missing_symbols.cpp
@@ -52,7 +47,7 @@ SharedLibrary libmedia.so :
TimeSource.cpp TimeSource.cpp
# Internal Functionality # Internal Functionality
BufferIdCache.cpp BufferCache.cpp
DataExchange.cpp DataExchange.cpp
DefaultMediaTheme.cpp DefaultMediaTheme.cpp
DormantNodeManager.cpp DormantNodeManager.cpp
+1 -1
View File
@@ -617,7 +617,7 @@ BMediaAddOn::NotifyFlavorChange()
return B_ERROR; return B_ERROR;
addonserver_rescan_mediaaddon_flavors_command command; addonserver_rescan_mediaaddon_flavors_command command;
command.addonid = fAddon; command.addon_id = fAddon;
return SendToAddonServer(ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS, &command, sizeof(command)); return SendToAddonServer(ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS, &command, sizeof(command));
} }
+109 -109
View File
@@ -31,7 +31,6 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
*/ */
@@ -39,7 +38,7 @@
char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus " char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "
"Overhagen <[email protected]>"; "Overhagen <[email protected]>";
//#define DEBUG 7
#include <MediaRoster.h> #include <MediaRoster.h>
#include <new> #include <new>
@@ -56,6 +55,8 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "
#include <String.h> #include <String.h>
#include <TimeSource.h> #include <TimeSource.h>
#include <AppMisc.h>
#include "debug.h" #include "debug.h"
#include "MediaRosterEx.h" #include "MediaRosterEx.h"
#include "MediaMisc.h" #include "MediaMisc.h"
@@ -68,39 +69,43 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "
namespace BPrivate { namespace media { namespace BPrivate { namespace media {
// the BMediaRoster destructor is private, // the BMediaRoster destructor is private,
// but _DefaultDeleter is a friend class of // but _DefaultDeleter is a friend class of
// the BMediaRoster an thus can delete it // the BMediaRoster an thus can delete it
class DefaultDeleter class DefaultDeleter {
public:
~DefaultDeleter()
{ {
public: if (BMediaRoster::sDefaultInstance != NULL) {
~DefaultDeleter() BMediaRoster::sDefaultInstance->Lock();
{ BMediaRoster::sDefaultInstance->Quit();
if (BMediaRoster::sDefaultInstance) {
BMediaRoster::sDefaultInstance->Lock();
BMediaRoster::sDefaultInstance->Quit();
}
} }
}; }
};
} // namespace media
} // namespace BPrivate
} } // BPrivate::media
using namespace BPrivate::media; using namespace BPrivate::media;
// DefaultDeleter will delete the BMediaRoster object in it's destructor. // DefaultDeleter will delete the BMediaRoster object in it's destructor.
DefaultDeleter _deleter; DefaultDeleter _deleter;
BMediaRosterEx::BMediaRosterEx(status_t* _error) BMediaRosterEx::BMediaRosterEx(status_t* _error)
: BMediaRoster() :
BMediaRoster()
{ {
status_t rv;
// register this application with the media server // register this application with the media server
server_register_app_request request; server_register_app_request request;
server_register_app_reply reply; server_register_app_reply reply;
request.team = team; request.team = BPrivate::current_team();
request.messenger = BMessenger(NULL, this); request.messenger = BMessenger(NULL, this);
rv = QueryServer(SERVER_REGISTER_APP, &request, sizeof(request), &reply,
sizeof(reply)); status_t status = QueryServer(SERVER_REGISTER_APP, &request,
if (rv != B_OK) sizeof(request), &reply, sizeof(reply));
if (status != B_OK)
*_error = B_MEDIA_SYSTEM_FAILURE; *_error = B_MEDIA_SYSTEM_FAILURE;
else else
*_error = B_OK; *_error = B_OK;
@@ -110,11 +115,9 @@ BMediaRosterEx::BMediaRosterEx(status_t* _error)
status_t status_t
BMediaRosterEx::SaveNodeConfiguration(BMediaNode* node) BMediaRosterEx::SaveNodeConfiguration(BMediaNode* node)
{ {
BMediaAddOn *addon; int32 flavorID;
media_addon_id addonid; BMediaAddOn* addon = node->AddOn(&flavorID);
int32 flavorid; if (addon == NULL) {
addon = node->AddOn(&flavorid);
if (!addon) {
// NOTE: This node could have been created by an application, // NOTE: This node could have been created by an application,
// it does not mean there is an error. // it does not mean there is an error.
// TODO: this check incorrectly triggers on BeOS R5 BT848 node // TODO: this check incorrectly triggers on BeOS R5 BT848 node
@@ -122,54 +125,55 @@ BMediaRosterEx::SaveNodeConfiguration(BMediaNode* node)
"from BMediaAddOn!\n", node->ID()); "from BMediaAddOn!\n", node->ID());
return B_ERROR; return B_ERROR;
} }
addonid = addon->AddonID();
media_addon_id addonID = addon->AddonID();
// TODO: fix this // TODO: fix this
printf("### BMediaRosterEx::SaveNodeConfiguration should save addon-id " printf("### BMediaRosterEx::SaveNodeConfiguration should save addon-id "
"%ld, flavor-id %ld config NOW!\n", addonid, flavorid); "%ld, flavor-id %ld config NOW!\n", addonID, flavorID);
return B_OK; return B_OK;
} }
status_t status_t
BMediaRosterEx::LoadNodeConfiguration(media_addon_id addonid, int32 flavorid, BMediaRosterEx::LoadNodeConfiguration(media_addon_id addonID, int32 flavorID,
BMessage *out_msg) BMessage *_msg)
{ {
// TODO: fix this // TODO: fix this
out_msg->MakeEmpty(); // to be fully R5 compliant _msg->MakeEmpty(); // to be fully R5 compliant
printf("### BMediaRosterEx::LoadNodeConfiguration should load addon-id " printf("### BMediaRosterEx::LoadNodeConfiguration should load addon-id "
"%ld, flavor-id %ld config NOW!\n", addonid, flavorid); "%ld, flavor-id %ld config NOW!\n", addonID, flavorID);
return B_OK; return B_OK;
} }
status_t status_t
BMediaRosterEx::IncrementAddonFlavorInstancesCount(media_addon_id addonid, BMediaRosterEx::IncrementAddonFlavorInstancesCount(media_addon_id addonID,
int32 flavorid) int32 flavorID)
{ {
server_change_addon_flavor_instances_count_request request; server_change_addon_flavor_instances_count_request request;
server_change_addon_flavor_instances_count_reply reply; server_change_addon_flavor_instances_count_reply reply;
request.addonid = addonid; request.addon_id = addonID;
request.flavorid = flavorid; request.flavor_id = flavorID;
request.delta = 1; request.delta = 1;
request.team = team; request.team = BPrivate::current_team();
return QueryServer(SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT, &request, return QueryServer(SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT, &request,
sizeof(request), &reply, sizeof(reply)); sizeof(request), &reply, sizeof(reply));
} }
status_t status_t
BMediaRosterEx::DecrementAddonFlavorInstancesCount(media_addon_id addonid, BMediaRosterEx::DecrementAddonFlavorInstancesCount(media_addon_id addonID,
int32 flavorid) int32 flavorID)
{ {
server_change_addon_flavor_instances_count_request request; server_change_addon_flavor_instances_count_request request;
server_change_addon_flavor_instances_count_reply reply; server_change_addon_flavor_instances_count_reply reply;
request.addonid = addonid; request.addon_id = addonID;
request.flavorid = flavorid; request.flavor_id = flavorID;
request.delta = -1; request.delta = -1;
request.team = team; request.team = BPrivate::current_team();
return QueryServer(SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT, &request, return QueryServer(SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT, &request,
sizeof(request), &reply, sizeof(reply)); sizeof(request), &reply, sizeof(reply));
} }
@@ -200,7 +204,7 @@ BMediaRosterEx::GetNode(node_type type, media_node* out_node,
status_t rv; status_t rv;
request.type = type; request.type = type;
request.team = team; request.team = BPrivate::current_team();
rv = QueryServer(SERVER_GET_NODE, &request, sizeof(request), &reply, rv = QueryServer(SERVER_GET_NODE, &request, sizeof(request), &reply,
sizeof(reply)); sizeof(reply));
if (rv != B_OK) if (rv != B_OK)
@@ -673,8 +677,8 @@ BMediaRoster::GetNodeFor(media_node_id node, media_node* clone)
server_get_node_for_reply reply; server_get_node_for_reply reply;
status_t rv; status_t rv;
request.nodeid = node; request.node_id = node;
request.team = team; request.team = BPrivate::current_team();
rv = QueryServer(SERVER_GET_NODE_FOR, &request, sizeof(request), &reply, rv = QueryServer(SERVER_GET_NODE_FOR, &request, sizeof(request), &reply,
sizeof(reply)); sizeof(reply));
@@ -720,7 +724,7 @@ BMediaRoster::ReleaseNode(const media_node& node)
if (node.kind & NODE_KIND_NO_REFCOUNTING) { if (node.kind & NODE_KIND_NO_REFCOUNTING) {
printf("BMediaRoster::ReleaseNode, trying to release reference " printf("BMediaRoster::ReleaseNode, trying to release reference "
"counting disabled timesource, node %ld, port %ld, team %ld\n", "counting disabled timesource, node %ld, port %ld, team %ld\n",
node.node, node.port, team); node.node, node.port, BPrivate::current_team());
return B_OK; return B_OK;
} }
@@ -729,16 +733,16 @@ BMediaRoster::ReleaseNode(const media_node& node)
status_t rv; status_t rv;
request.node = node; request.node = node;
request.team = team; request.team = BPrivate::current_team();
TRACE("BMediaRoster::ReleaseNode, node %ld, port %ld, team %ld\n", TRACE("BMediaRoster::ReleaseNode, node %ld, port %ld, team %ld\n",
node.node, node.port, team); node.node, node.port, BPrivate::current_team());
rv = QueryServer(SERVER_RELEASE_NODE, &request, sizeof(request), &reply, rv = QueryServer(SERVER_RELEASE_NODE, &request, sizeof(request), &reply,
sizeof(reply)); sizeof(reply));
if (rv != B_OK) { if (rv != B_OK) {
ERROR("BMediaRoster::ReleaseNode FAILED, node %ld, port %ld, team " ERROR("BMediaRoster::ReleaseNode FAILED, node %ld, port %ld, team "
"%ld!\n", node.node, node.port, team); "%ld!\n", node.node, node.port, BPrivate::current_team());
} }
return rv; return rv;
} }
@@ -1880,8 +1884,8 @@ BMediaRoster::RegisterNode(BMediaNode* node)
status_t status_t
BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addonid, BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addonID,
int32 flavorid) int32 flavorID)
{ {
CALLED(); CALLED();
if (node == NULL) if (node == NULL)
@@ -1890,27 +1894,24 @@ BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addonid,
// some sanity check // some sanity check
// I'm not sure if the media kit warrants to call BMediaNode::AddOn() here. // I'm not sure if the media kit warrants to call BMediaNode::AddOn() here.
// Perhaps we don't need it. // Perhaps we don't need it.
{ DEBUG_ONLY(
BMediaAddOn *addon; int32 testFlavorID;
int32 addon_flavor_id; BMediaAddOn* addon = node->AddOn(&testFlavorID);
media_addon_id addon_id;
addon_flavor_id = 0; ASSERT(addonID == addon != NULL ? addon->AddonID() : -1);
addon = node->AddOn(&addon_flavor_id); ASSERT(flavorID == testFlavorID);
addon_id = addon ? addon->AddonID() : -1; );
ASSERT(addonid == addon_id);
ASSERT(flavorid == addon_flavor_id);
}
status_t rv; status_t rv;
server_register_node_request request; server_register_node_request request;
server_register_node_reply reply; server_register_node_reply reply;
request.addon_id = addonid; request.addon_id = addonID;
request.addon_flavor_id = flavorid; request.addon_flavor_id = flavorID;
strcpy(request.name, node->Name()); strcpy(request.name, node->Name());
request.kinds = node->Kinds(); request.kinds = node->Kinds();
request.port = node->ControlPort(); request.port = node->ControlPort();
request.team = team; request.team = BPrivate::current_team();
TRACE("BMediaRoster::RegisterNode: sending SERVER_REGISTER_NODE: port " TRACE("BMediaRoster::RegisterNode: sending SERVER_REGISTER_NODE: port "
"%ld, kinds 0x%Lx, team %ld, name '%s'\n", request.port, request.kinds, "%ld, kinds 0x%Lx, team %ld, name '%s'\n", request.port, request.kinds,
@@ -1928,9 +1929,9 @@ BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addonid,
"finished\n"); "finished\n");
// we are a friend class of BMediaNode and initialize this member variable // we are a friend class of BMediaNode and initialize this member variable
node->fNodeID = reply.nodeid; node->fNodeID = reply.node_id;
ASSERT(reply.nodeid == node->Node().node); ASSERT(reply.node_id == node->Node().node);
ASSERT(reply.nodeid == node->ID()); ASSERT(reply.node_id == node->ID());
// call the callback // call the callback
node->NodeRegistered(); node->NodeRegistered();
@@ -1964,19 +1965,18 @@ BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addonid,
PublishOutputs(node->Node(), &list); PublishOutputs(node->Node(), &list);
} }
} }
if (node->Kinds() & B_BUFFER_CONSUMER) { if ((node->Kinds() & B_BUFFER_CONSUMER) != 0) {
BBufferConsumer *bc; BBufferConsumer* consumer = dynamic_cast<BBufferConsumer*>(node);
bc = dynamic_cast<BBufferConsumer *>(node); if (consumer != NULL) {
if (bc) {
List<media_input> list; List<media_input> list;
if (B_OK == GetAllInputs(bc, &list)) if (GetAllInputs(consumer, &list) == B_OK)
PublishInputs(node->Node(), &list); PublishInputs(node->Node(), &list);
} }
} }
TRACE("BMediaRoster::RegisterNode: sending NodesCreated\n"); TRACE("BMediaRoster::RegisterNode: sending NodesCreated\n");
BPrivate::media::notifications::NodesCreated(&reply.nodeid, 1); BPrivate::media::notifications::NodesCreated(&reply.node_id, 1);
TRACE("BMediaRoster::RegisterNode: finished\n"); TRACE("BMediaRoster::RegisterNode: finished\n");
@@ -2005,7 +2005,7 @@ BMediaRoster::UnregisterNode(BMediaNode* node)
if (node->fKinds & NODE_KIND_NO_REFCOUNTING) { if (node->fKinds & NODE_KIND_NO_REFCOUNTING) {
TRACE("BMediaRoster::UnregisterNode, trying to unregister reference " TRACE("BMediaRoster::UnregisterNode, trying to unregister reference "
"counting disabled timesource, node %ld, port %ld, team %ld\n", "counting disabled timesource, node %ld, port %ld, team %ld\n",
node->ID(), node->ControlPort(), team); node->ID(), node->ControlPort(), BPrivate::current_team());
return B_OK; return B_OK;
} }
if (node->ID() == NODE_UNREGISTERED_ID) { if (node->ID() == NODE_UNREGISTERED_ID) {
@@ -2030,11 +2030,11 @@ BMediaRoster::UnregisterNode(BMediaNode* node)
server_unregister_node_reply reply; server_unregister_node_reply reply;
status_t rv; status_t rv;
request.nodeid = node->ID(); request.node_id = node->ID();
request.team = team; request.team = BPrivate::current_team();
// send a notification // send a notification
BPrivate::media::notifications::NodesDeleted(&request.nodeid, 1); BPrivate::media::notifications::NodesDeleted(&request.node_id, 1);
rv = QueryServer(SERVER_UNREGISTER_NODE, &request, sizeof(request), &reply, rv = QueryServer(SERVER_UNREGISTER_NODE, &request, sizeof(request), &reply,
sizeof(reply)); sizeof(reply));
@@ -2044,17 +2044,17 @@ BMediaRoster::UnregisterNode(BMediaNode* node)
return rv; return rv;
} }
if (reply.addonid != -1) { if (reply.addon_id != -1) {
// Small problem here, we can't use DormantNodeManager::PutAddon(), as // Small problem here, we can't use DormantNodeManager::PutAddon(), as
// UnregisterNode() is called by a dormant node itself (by the // UnregisterNode() is called by a dormant node itself (by the
// destructor). // destructor).
// The add-on that contains the node needs to remain in memory until the // The add-on that contains the node needs to remain in memory until the
// destructor execution is finished. // destructor execution is finished.
// DormantNodeManager::PutAddonDelayed() will delay unloading. // DormantNodeManager::PutAddonDelayed() will delay unloading.
_DormantNodeManager->PutAddonDelayed(reply.addonid); _DormantNodeManager->PutAddonDelayed(reply.addon_id);
rv = MediaRosterEx(this)->DecrementAddonFlavorInstancesCount( rv = MediaRosterEx(this)->DecrementAddonFlavorInstancesCount(
reply.addonid, reply.flavorid); reply.addon_id, reply.flavor_id);
if (rv != B_OK) { if (rv != B_OK) {
ERROR("BMediaRoster::UnregisterNode: " ERROR("BMediaRoster::UnregisterNode: "
"DecrementAddonFlavorInstancesCount() failed\n"); "DecrementAddonFlavorInstancesCount() failed\n");
@@ -2275,16 +2275,16 @@ BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count,
if (port <= B_OK) if (port <= B_OK)
return B_ERROR; return B_ERROR;
msg.maxcount = *_count; msg.max_count = *_count;
msg.has_input = hasInput != NULL; msg.has_input = hasInput != NULL;
if (hasInput != NULL) { if (hasInput != NULL) {
// TODO: we should not make a flat copy of media_format // TODO: we should not make a flat copy of media_format
msg.inputformat = *hasInput; msg.input_format = *hasInput;
} }
msg.has_output = hasOutput != NULL; msg.has_output = hasOutput != NULL;
if (hasOutput != NULL) { if (hasOutput != NULL) {
// TODO: we should not make a flat copy of media_format // TODO: we should not make a flat copy of media_format
msg.outputformat = *hasOutput; msg.output_format = *hasOutput;
} }
msg.has_name = name != NULL; msg.has_name = name != NULL;
@@ -2459,7 +2459,7 @@ BMediaRosterEx::InstantiateDormantNode(media_addon_id addonID, int32 flavorID,
TRACE("BMediaRosterEx::InstantiateDormantNode: addon-id %ld, flavor_id " TRACE("BMediaRosterEx::InstantiateDormantNode: addon-id %ld, flavor_id "
"%ld instanciated as node %ld, port %ld in team %ld\n", addonID, "%ld instanciated as node %ld, port %ld in team %ld\n", addonID,
flavorID, _node->node, _node->port, team); flavorID, _node->node, _node->port, BPrivate::current_team());
return B_OK; return B_OK;
} }
@@ -2548,9 +2548,9 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info& info,
addonserver_instantiate_dormant_node_request request; addonserver_instantiate_dormant_node_request request;
addonserver_instantiate_dormant_node_reply reply; addonserver_instantiate_dormant_node_reply reply;
request.addonid = info.addon; request.addon_id = info.addon;
request.flavorid = info.flavor_id; request.flavor_id = info.flavor_id;
request.creator_team = team; request.creator_team = BPrivate::current_team();
// creator team is allowed to also release global nodes // creator team is allowed to also release global nodes
rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request, rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request,
sizeof(request), &reply, sizeof(reply)); sizeof(request), &reply, sizeof(reply));
@@ -2611,44 +2611,44 @@ BMediaRosterEx::GetDormantFlavorInfo(media_addon_id addonID, int32 flavorID,
if (_flavor == NULL) if (_flavor == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
xfer_server_get_dormant_flavor_info msg; port_id port = find_port(MEDIA_SERVER_PORT_NAME);
xfer_server_get_dormant_flavor_info_reply *reply; if (port < 0)
port_id port;
status_t rv;
int32 code;
port = find_port(MEDIA_SERVER_PORT_NAME);
if (port < B_OK)
return B_ERROR; return B_ERROR;
reply = (xfer_server_get_dormant_flavor_info_reply*)malloc(16000); xfer_server_get_dormant_flavor_info_reply* reply
= (xfer_server_get_dormant_flavor_info_reply*)malloc(16300);
if (reply == NULL) if (reply == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
xfer_server_get_dormant_flavor_info msg;
msg.addon = addonID; msg.addon = addonID;
msg.flavor_id = flavorID; msg.flavor_id = flavorID;
msg.reply_port = _PortPool->GetPort(); msg.reply_port = _PortPool->GetPort();
rv = write_port(port, SERVER_GET_DORMANT_FLAVOR_INFO, &msg, sizeof(msg)); status_t status = write_port(port, SERVER_GET_DORMANT_FLAVOR_INFO, &msg,
if (rv != B_OK) { sizeof(msg));
if (status != B_OK) {
free(reply); free(reply);
_PortPool->PutPort(msg.reply_port); _PortPool->PutPort(msg.reply_port);
return rv; return status;
} }
rv = read_port(msg.reply_port, &code, reply, 16000);
int32 code;
status = read_port(msg.reply_port, &code, reply, 16000);
_PortPool->PutPort(msg.reply_port); _PortPool->PutPort(msg.reply_port);
if (rv < B_OK) { if (status < B_OK) {
free(reply); free(reply);
return rv; return status;
} }
if (reply->result == B_OK) if (reply->result == B_OK) {
rv = _flavor->Unflatten(reply->dfi_type, &reply->dfi, reply->dfi_size); status = _flavor->Unflatten(reply->type, &reply->flattened_data,
else reply->flattened_size);
rv = reply->result; } else
status = reply->result;
free(reply); free(reply);
return rv; return status;
} }
@@ -3028,7 +3028,7 @@ BMediaRoster::NodeIDFor(port_id port)
return -1; return -1;
} }
return reply.nodeid; return reply.node_id;
} }
@@ -3202,7 +3202,7 @@ BMediaRoster::~BMediaRoster()
// unregister this application with the media server // unregister this application with the media server
server_unregister_app_request request; server_unregister_app_request request;
server_unregister_app_reply reply; server_unregister_app_reply reply;
request.team = team; request.team = BPrivate::current_team();
QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply, QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply,
sizeof(reply)); sizeof(reply));
+74 -46
View File
@@ -24,78 +24,90 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * 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 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
*/ */
/* This is a interface class for media kit notifications.
* It is private to the media kit which uses it to pass /*! This is a interface class for media kit notifications.
* notifications up to the media_server which will broadcast It is private to the media kit which uses it to pass notifications up to
* them. the media_server which will broadcast them.
*/ */
/* XXX The BeBook, MediaDefs.h and the BeOS R5 do list
* XXX different strings for the message data fields of // TODO: The BeBook, MediaDefs.h and the BeOS R5 do list
* XXX the notification messages. // different strings for the message data fields of
*/ // the notification messages.
#include "Notifications.h"
#include <Messenger.h> #include <Messenger.h>
#include <MediaNode.h> #include <MediaNode.h>
#include <AppMisc.h>
#include "debug.h" #include "debug.h"
#include "DataExchange.h" #include "DataExchange.h"
#include "Notifications.h"
namespace BPrivate { namespace BPrivate {
namespace media { namespace media {
extern team_id team;
namespace notifications { namespace notifications {
status_t status_t
Register(const BMessenger &notifyHandler, const media_node &node, int32 notification) Register(const BMessenger& notifyHandler, const media_node& node,
int32 notification)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification); msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
msg.AddInt32(NOTIFICATION_PARAM_TEAM, team); msg.AddInt32(NOTIFICATION_PARAM_TEAM, BPrivate::current_team());
msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler); msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node)); msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
return BPrivate::media::dataexchange::SendToServer(&msg); return BPrivate::media::dataexchange::SendToServer(&msg);
} }
status_t status_t
Unregister(const BMessenger &notifyHandler, const media_node &node, int32 notification) Unregister(const BMessenger& notifyHandler, const media_node& node,
int32 notification)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification); msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
msg.AddInt32(NOTIFICATION_PARAM_TEAM, team); msg.AddInt32(NOTIFICATION_PARAM_TEAM, BPrivate::current_team());
msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler); msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node)); msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
return BPrivate::media::dataexchange::SendToServer(&msg); return BPrivate::media::dataexchange::SendToServer(&msg);
} }
/*! Transmits the error code specified by \a what to anyone who's receiving
notifications from this node. If \a info isn't \c NULL, it's used as a
model message for the error notification message.
The message field "be:node_id" will contain the node ID.
*/
status_t status_t
ReportError(const media_node &node, BMediaNode::node_error what, const BMessage * info) ReportError(const media_node& node, BMediaNode::node_error what,
const BMessage* info)
{ {
/* Transmits the error code specified by whichError to anyone that's receiving notifications from
* this node. If info isn't NULL, it's used as a model message for the error notification message.
* The message field "be:node_id" will contain the node ID.
*/
CALLED(); CALLED();
BMessage msg; BMessage msg;
if (info) if (info != NULL)
msg = *info; msg = *info;
msg.what = MEDIA_SERVER_SEND_NOTIFICATIONS; msg.what = MEDIA_SERVER_SEND_NOTIFICATIONS;
msg.AddInt32(NOTIFICATION_PARAM_WHAT, what); msg.AddInt32(NOTIFICATION_PARAM_WHAT, what);
msg.AddInt32("be:node_id", node.node); msg.AddInt32("be:node_id", node.node);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node)); msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
return BPrivate::media::dataexchange::SendToServer(&msg); return BPrivate::media::dataexchange::SendToServer(&msg);
} }
void void
NodesCreated(const media_node_id *ids, int32 count) NodesCreated(const media_node_id* ids, int32 count)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
@@ -103,12 +115,13 @@ NodesCreated(const media_node_id *ids, int32 count)
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
msg.AddInt32("media_node_id", ids[i]); msg.AddInt32("media_node_id", ids[i]);
} }
BPrivate::media::dataexchange::SendToServer(&msg); BPrivate::media::dataexchange::SendToServer(&msg);
} }
void void
NodesDeleted(const media_node_id *ids, int32 count) NodesDeleted(const media_node_id* ids, int32 count)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
@@ -116,12 +129,14 @@ NodesDeleted(const media_node_id *ids, int32 count)
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
msg.AddInt32("media_node_id", ids[i]); msg.AddInt32("media_node_id", ids[i]);
} }
BPrivate::media::dataexchange::SendToServer(&msg); BPrivate::media::dataexchange::SendToServer(&msg);
} }
void void
ConnectionMade(const media_input &input, const media_output &output, const media_format &format) ConnectionMade(const media_input& input, const media_output& output,
const media_format& format)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
@@ -129,24 +144,27 @@ ConnectionMade(const media_input &input, const media_output &output, const media
msg.AddData("input", B_RAW_TYPE, &input, sizeof(input)); msg.AddData("input", B_RAW_TYPE, &input, sizeof(input));
msg.AddData("output", B_RAW_TYPE, &output, sizeof(output)); msg.AddData("output", B_RAW_TYPE, &output, sizeof(output));
msg.AddData("format", B_RAW_TYPE, &format, sizeof(format)); msg.AddData("format", B_RAW_TYPE, &format, sizeof(format));
BPrivate::media::dataexchange::SendToServer(&msg); BPrivate::media::dataexchange::SendToServer(&msg);
} }
void void
ConnectionBroken(const media_source &source, const media_destination &destination) ConnectionBroken(const media_source& source,
const media_destination& destination)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_BROKEN); msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_BROKEN);
msg.AddData("source", B_RAW_TYPE, &source, sizeof(source)); msg.AddData("source", B_RAW_TYPE, &source, sizeof(source));
msg.AddData("destination", B_RAW_TYPE, &destination, sizeof(destination)); msg.AddData("destination", B_RAW_TYPE, &destination, sizeof(destination));
BPrivate::media::dataexchange::SendToServer(&msg); BPrivate::media::dataexchange::SendToServer(&msg);
} }
void void
BuffersCreated(area_info *areas, int32 count) BuffersCreated(area_info* areas, int32 count)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
@@ -154,12 +172,13 @@ BuffersCreated(area_info *areas, int32 count)
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
msg.AddData("clone_info", B_RAW_TYPE, &areas[i], sizeof(area_info)); msg.AddData("clone_info", B_RAW_TYPE, &areas[i], sizeof(area_info));
} }
BPrivate::media::dataexchange::SendToServer(&msg); BPrivate::media::dataexchange::SendToServer(&msg);
} }
void void
BuffersDeleted(const media_buffer_id *ids, int32 count) BuffersDeleted(const media_buffer_id* ids, int32 count)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
@@ -167,12 +186,14 @@ BuffersDeleted(const media_buffer_id *ids, int32 count)
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
msg.AddInt32("media_buffer_id", ids[i]); msg.AddInt32("media_buffer_id", ids[i]);
} }
BPrivate::media::dataexchange::SendToServer(&msg); BPrivate::media::dataexchange::SendToServer(&msg);
} }
void void
FormatChanged(const media_source &source, const media_destination &destination, const media_format &format) FormatChanged(const media_source& source, const media_destination& destination,
const media_format& format)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
@@ -180,74 +201,81 @@ FormatChanged(const media_source &source, const media_destination &destination,
msg.AddData("source", B_RAW_TYPE, &source, sizeof(source)); msg.AddData("source", B_RAW_TYPE, &source, sizeof(source));
msg.AddData("destination", B_RAW_TYPE, &destination, sizeof(destination)); msg.AddData("destination", B_RAW_TYPE, &destination, sizeof(destination));
msg.AddData("format", B_RAW_TYPE, &format, sizeof(format)); msg.AddData("format", B_RAW_TYPE, &format, sizeof(format));
BPrivate::media::dataexchange::SendToServer(&msg); BPrivate::media::dataexchange::SendToServer(&msg);
} }
status_t status_t
ParameterChanged(const media_node &node, int32 parameterid) ParameterChanged(const media_node& node, int32 parameterID)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_PARAMETER_CHANGED); msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_PARAMETER_CHANGED);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node)); msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
msg.AddInt32("parameter", parameterid); msg.AddInt32("parameter", parameterID);
return BPrivate::media::dataexchange::SendToServer(&msg); return BPrivate::media::dataexchange::SendToServer(&msg);
} }
void void
WebChanged(const media_node &node) WebChanged(const media_node& node)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_WEB_CHANGED); msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_WEB_CHANGED);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node)); msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
BPrivate::media::dataexchange::SendToServer(&msg); BPrivate::media::dataexchange::SendToServer(&msg);
} }
status_t status_t
NewParameterValue(const media_node &node, int32 parameterid, bigtime_t when, const void *param, size_t paramsize) NewParameterValue(const media_node& node, int32 parameterID, bigtime_t when,
const void* param, size_t paramsize)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NEW_PARAMETER_VALUE); msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NEW_PARAMETER_VALUE);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node)); msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
msg.AddInt32("parameter", parameterid); msg.AddInt32("parameter", parameterID);
msg.AddInt64("when", when); msg.AddInt64("when", when);
msg.AddData("value", B_RAW_TYPE, param, paramsize); msg.AddData("value", B_RAW_TYPE, param, paramsize);
return BPrivate::media::dataexchange::SendToServer(&msg); return BPrivate::media::dataexchange::SendToServer(&msg);
} }
void void
FlavorsChanged(media_addon_id addonid, int32 newcount, int32 gonecount) FlavorsChanged(media_addon_id addOnID, int32 newCount, int32 goneCount)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FLAVORS_CHANGED); msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FLAVORS_CHANGED);
msg.AddInt32("be:addon_id", addonid); msg.AddInt32("be:addon_id", addOnID);
msg.AddInt32("be:new_count", newcount); msg.AddInt32("be:new_count", newCount);
msg.AddInt32("be:gone_count", gonecount); msg.AddInt32("be:gone_count", goneCount);
BPrivate::media::dataexchange::SendToServer(&msg); BPrivate::media::dataexchange::SendToServer(&msg);
} }
void void
NodeStopped(const media_node &node, bigtime_t when) NodeStopped(const media_node& node, bigtime_t when)
{ {
CALLED(); CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS); BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_STOPPED); msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_STOPPED);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node)); msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
msg.AddInt64("when", when); msg.AddInt64("when", when);
BPrivate::media::dataexchange::SendToServer(&msg); BPrivate::media::dataexchange::SendToServer(&msg);
} }
// XXX missing: B_MEDIA_TRANSPORT_STATE /* "state", "location", "realtime" */ // TODO: missing: B_MEDIA_TRANSPORT_STATE: "state", "location", "realtime"
// XXX missing: B_MEDIA_DEFAULT_CHANGED /* "default", "node" */ // TODO: missing: B_MEDIA_DEFAULT_CHANGED: "default", "node"
bool bool
@@ -281,6 +309,6 @@ IsValidNotificationRequest(bool node_specific, int32 notification)
} }
} }
}; // namespace notifications } // namespace notifications
}; // namespace media } // namespace media
}; // namespace BPrivate } // namespace BPrivate
+246 -185
View File
@@ -1,213 +1,241 @@
/*********************************************************************** /*
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved. * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the OpenBeOS License. * Copyright 2002, Marcus Overhagen. All Rights Reserved.
* * Distributed under the terms of the MIT License.
* Used for BBufferGroup and BBuffer management across teams */
***********************************************************************/
#include <Buffer.h>
/*! Used for BBufferGroup and BBuffer management across teams.
Created in the media server, cloned into each BBufferGroup (visible in
all address spaces).
*/
// TODO: don't use a simple list!
#include <SharedBufferList.h>
#include <string.h> #include <string.h>
#include "SharedBufferList.h"
#include <Buffer.h>
#include "debug.h" #include "debug.h"
status_t namespace BPrivate {
_shared_buffer_list::Init()
/*static*/ area_id
SharedBufferList::Create(SharedBufferList** _list)
{ {
CALLED(); CALLED();
locker_atom = 0;
locker_sem = create_sem(0,"shared buffer list lock");
if (locker_sem < B_OK)
return (status_t) locker_sem;
for (int i = 0; i < MAX_BUFFER; i++) { size_t size = (sizeof(SharedBufferList) + (B_PAGE_SIZE - 1))
info[i].id = -1; & ~(B_PAGE_SIZE - 1);
info[i].buffer = 0; SharedBufferList* list;
info[i].reclaim_sem = 0;
info[i].reclaimed = false; area_id area = create_area("shared buffer list", (void**)&list,
B_ANY_ADDRESS, size, B_LAZY_LOCK, B_READ_AREA | B_WRITE_AREA);
if (area < 0)
return area;
status_t status = list->_Init();
if (status != B_OK) {
delete_area(area);
return status;
} }
return B_OK;
return area;
} }
_shared_buffer_list *
_shared_buffer_list::Clone(area_id id) /*static*/ SharedBufferList*
SharedBufferList::Get(area_id id)
{ {
CALLED(); CALLED();
// if id == -1, we are in the media_server team, // TODO: map this only once per team!
// and create the initial list, else we clone it
_shared_buffer_list *adr; SharedBufferList* list;
status_t status; area_id area = clone_area("shared buffer list clone", (void**)&list,
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, id);
if (id == -1) { if (area < 0) {
size_t size = ((sizeof(_shared_buffer_list)) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1); ERROR("SharedBufferList::Clone() clone area: %ld err = %s\n", id,
status = create_area("shared buffer list",(void **)&adr,B_ANY_ADDRESS,size,B_LAZY_LOCK,B_READ_AREA | B_WRITE_AREA); strerror(area));
if (status >= B_OK) { return NULL;
status = adr->Init();
if (status != B_OK)
delete_area(area_for(adr));
}
} else {
status = clone_area("shared buffer list clone", (void **)&adr, B_ANY_ADDRESS, B_READ_AREA|B_WRITE_AREA, id);
if (status < B_OK) {
ERROR("_shared_buffer_list::Clone() clone area: %ld err = %s\n", id, strerror(status));
}
} }
return (status < B_OK) ? NULL : adr; return list;
} }
void void
_shared_buffer_list::Unmap() SharedBufferList::Put()
{ {
CALLED(); CALLED();
// unmap the memory used by this struct
// XXX is this save? area_id area = area_for(this);
area_id id; if (area >= 0)
id = area_for(this); delete_area(area);
if (id >= B_OK)
delete_area(id);
} }
/*! Deletes all BBuffers of the group specified by \a groupReclaimSem, then
unmaps the list from memory.
*/
void void
_shared_buffer_list::Terminate(sem_id group_reclaim_sem) SharedBufferList::DeleteGroupAndPut(sem_id groupReclaimSem)
{ {
CALLED(); CALLED();
// delete all BBuffers of this group, then unmap from memory if (Lock() == B_OK) {
for (int32 i = 0; i < fCount; i++) {
if (fInfos[i].reclaim_sem == groupReclaimSem) {
// delete the associated buffer
delete fInfos[i].buffer;
if (Lock() != B_OK) { // better not try to access the list unlocked // Decrement buffer count by one, and fill the gap
// but at least try to unmap the memory // in the list with its last entry
Unmap(); fCount--;
return; if (fCount > 0)
} fInfos[i--] = fInfos[fCount];
for (int32 i = 0; i < buffercount; i++) {
if (info[i].reclaim_sem == group_reclaim_sem) {
// delete the associated buffer
delete info[i].buffer;
// decrement buffer count by one
buffercount--;
// fill the gap in the list with the last entry
if (buffercount > 0) {
info[i] = info[buffercount];
i--; // make sure we check this entry again
} }
} }
Unlock();
} }
Unlock(); Put();
Unmap();
} }
status_t status_t
_shared_buffer_list::Lock() SharedBufferList::Lock()
{ {
if (atomic_add(&locker_atom, 1) > 0) { if (atomic_add(&fAtom, 1) > 0) {
status_t status; status_t status;
while (B_INTERRUPTED == (status = acquire_sem(locker_sem))) do {
; status = acquire_sem(fSemaphore);
return status; // will only return != B_OK if the media_server crashed or quit } while (status == B_INTERRUPTED);
return status;
} }
return B_OK; return B_OK;
} }
status_t status_t
_shared_buffer_list::Unlock() SharedBufferList::Unlock()
{ {
if (atomic_add(&locker_atom, -1) > 1) if (atomic_add(&fAtom, -1) > 1)
return release_sem(locker_sem); // will only return != B_OK if the media_server crashed or quit return release_sem(fSemaphore);
return B_OK; return B_OK;
} }
status_t status_t
_shared_buffer_list::AddBuffer(sem_id group_reclaim_sem, BBuffer *buffer) SharedBufferList::AddBuffer(sem_id groupReclaimSem, BBuffer* buffer)
{ {
CALLED(); CALLED();
if (buffer == NULL) if (buffer == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
if (Lock() != B_OK) status_t status = Lock();
return B_ERROR; if (status != B_OK)
return status;
if (buffercount == MAX_BUFFER) { if (fCount == kMaxBuffers) {
Unlock(); Unlock();
debugger("we are doomed"); return B_MEDIA_TOO_MANY_BUFFERS;
return B_ERROR;
} }
info[buffercount].id = buffer->ID(); fInfos[fCount].id = buffer->ID();
info[buffercount].buffer = buffer; fInfos[fCount].buffer = buffer;
info[buffercount].reclaim_sem = group_reclaim_sem; fInfos[fCount].reclaim_sem = groupReclaimSem;
info[buffercount].reclaimed = true; fInfos[fCount].reclaimed = true;
buffercount++; fCount++;
status_t status1 = release_sem_etc(group_reclaim_sem,1,B_DO_NOT_RESCHEDULE); status = release_sem_etc(groupReclaimSem, 1, B_DO_NOT_RESCHEDULE);
status_t status2 = Unlock(); if (status != B_OK)
return status;
return (status1 == B_OK && status2 == B_OK) ? B_OK : B_ERROR; return Unlock();
} }
status_t status_t
_shared_buffer_list::RequestBuffer(sem_id group_reclaim_sem, int32 buffers_in_group, size_t size, media_buffer_id wantID, BBuffer **buffer, bigtime_t timeout) SharedBufferList::RequestBuffer(sem_id groupReclaimSem, int32 buffersInGroup,
size_t size, media_buffer_id wantID, BBuffer** _buffer, bigtime_t timeout)
{ {
CALLED(); CALLED();
// we always search for a buffer from the group indicated by group_reclaim_sem first // We always search for a buffer from the group indicated by groupReclaimSem
// if "size" != 0, we search for a buffer that is "size" bytes or larger // first.
// if "wantID" != 0, we search for a buffer with this id // If "size" != 0, we search for a buffer that is "size" bytes or larger.
// if "*buffer" != NULL, we search for a buffer at this address // If "wantID" != 0, we search for a buffer with this ID.
// if we found a buffer, we also need to mark it in all other groups as requested // If "*_buffer" != NULL, we search for a buffer at this address.
// and also once need to acquire the reclaim_sem of the other groups //
// If we found a buffer, we also need to mark it in all other groups as
// requested and also once need to acquire the reclaim_sem of the other
// groups
status_t status; uint32 acquireFlags;
uint32 acquire_flags;
int32 count;
if (timeout <= 0) { if (timeout <= 0) {
timeout = 0; timeout = 0;
acquire_flags = B_RELATIVE_TIMEOUT; acquireFlags = B_RELATIVE_TIMEOUT;
} else if (timeout != B_INFINITE_TIMEOUT) { } else if (timeout == B_INFINITE_TIMEOUT) {
timeout += system_time(); acquireFlags = B_RELATIVE_TIMEOUT;
acquire_flags = B_ABSOLUTE_TIMEOUT;
} else { } else {
//timeout is B_INFINITE_TIMEOUT timeout += system_time();
acquire_flags = B_RELATIVE_TIMEOUT; acquireFlags = B_ABSOLUTE_TIMEOUT;
} }
// with each itaration we request one more buffer, since we need to skip the buffers that don't fit the request // With each itaration we request one more buffer, since we need to skip
count = 1; // the buffers that don't fit the request
int32 count = 1;
do { do {
while (B_INTERRUPTED == (status = acquire_sem_etc(group_reclaim_sem, count, acquire_flags, timeout))) status_t status;
; do {
status = acquire_sem_etc(groupReclaimSem, count, acquireFlags,
timeout);
} while (status == B_INTERRUPTED);
if (status != B_OK) if (status != B_OK)
return status; return status;
// try to exit savely if the lock fails // try to exit savely if the lock fails
if (Lock() != B_OK) { status = Lock();
ERROR("_shared_buffer_list:: RequestBuffer: Lock failed\n"); if (status != B_OK) {
release_sem_etc(group_reclaim_sem, count, 0); ERROR("SharedBufferList:: RequestBuffer: Lock failed: %s\n",
strerror(status));
release_sem_etc(groupReclaimSem, count, 0);
return B_ERROR; return B_ERROR;
} }
for (int32 i = 0; i < buffercount; i++) { for (int32 i = 0; i < fCount; i++) {
// we need a BBuffer from the group, and it must be marked as reclaimed // We need a BBuffer from the group, and it must be marked as
if (info[i].reclaim_sem == group_reclaim_sem && info[i].reclaimed) { // reclaimed
if ( if (fInfos[i].reclaim_sem == groupReclaimSem
(size != 0 && size <= info[i].buffer->SizeAvailable()) || && fInfos[i].reclaimed) {
(*buffer != 0 && info[i].buffer == *buffer) || if ((size != 0 && size <= fInfos[i].buffer->SizeAvailable())
(wantID != 0 && info[i].id == wantID) || (*_buffer != 0 && fInfos[i].buffer == *_buffer)
) { || (wantID != 0 && fInfos[i].id == wantID)) {
// we found a buffer // we found a buffer
info[i].reclaimed = false; fInfos[i].reclaimed = false;
*buffer = info[i].buffer; *_buffer = fInfos[i].buffer;
// if we requested more than one buffer, release the rest
if (count > 1)
release_sem_etc(group_reclaim_sem, count - 1, B_DO_NOT_RESCHEDULE);
// and mark all buffers with the same ID as requested in all other buffer groups // if we requested more than one buffer, release the rest
RequestBufferInOtherGroups(group_reclaim_sem, info[i].buffer->ID()); if (count > 1) {
release_sem_etc(groupReclaimSem, count - 1,
B_DO_NOT_RESCHEDULE);
}
// And mark all buffers with the same ID as requested in
// all other buffer groups
_RequestBufferInOtherGroups(groupReclaimSem,
fInfos[i].buffer->ID());
Unlock(); Unlock();
return B_OK; return B_OK;
@@ -215,107 +243,140 @@ _shared_buffer_list::RequestBuffer(sem_id group_reclaim_sem, int32 buffers_in_gr
} }
} }
release_sem_etc(group_reclaim_sem, count, B_DO_NOT_RESCHEDULE); release_sem_etc(groupReclaimSem, count, B_DO_NOT_RESCHEDULE);
if (Unlock() != B_OK) { if (Unlock() != B_OK) {
ERROR("_shared_buffer_list:: RequestBuffer: unlock failed\n"); ERROR("SharedBufferList:: RequestBuffer: unlock failed\n");
return B_ERROR; return B_ERROR;
} }
// prepare to request one more buffer next time // prepare to request one more buffer next time
count++; count++;
} while (count <= buffers_in_group); } while (count <= buffersInGroup);
ERROR("_shared_buffer_list:: RequestBuffer: no buffer found\n"); ERROR("SharedBufferList:: RequestBuffer: no buffer found\n");
return B_ERROR; return B_ERROR;
} }
void
_shared_buffer_list::RequestBufferInOtherGroups(sem_id group_reclaim_sem, media_buffer_id id)
{
for (int32 i = 0; i < buffercount; i++) {
// find buffers with same id, but belonging to other groups
if (info[i].id == id && info[i].reclaim_sem != group_reclaim_sem) {
// and mark them as requested
// XXX this can deadlock if BBuffers with same media_buffer_id
// XXX exist in more than one BBufferGroup, and RequestBuffer()
// XXX is called on both groups (which should not be done).
status_t status;
while (B_INTERRUPTED == (status = acquire_sem(info[i].reclaim_sem)))
;
// try to skip entries that belong to crashed teams
if (status != B_OK)
continue;
if (info[i].reclaimed == false) {
ERROR("_shared_buffer_list:: RequestBufferInOtherGroups BBuffer %p, id = %ld not reclaimed while requesting\n", info[i].buffer, id);
continue;
}
info[i].reclaimed = false;
}
}
}
status_t status_t
_shared_buffer_list::RecycleBuffer(BBuffer *buffer) SharedBufferList::RecycleBuffer(BBuffer* buffer)
{ {
CALLED(); CALLED();
int reclaimed_count; media_buffer_id id = buffer->ID();
// media_buffer_id id = buffer->ID();
media_buffer_id id = buffer->fBufferID;
if (Lock() != B_OK) if (Lock() != B_OK)
return B_ERROR; return B_ERROR;
reclaimed_count = 0; int32 reclaimedCount = 0;
for (int32 i = 0; i < buffercount; i++) {
for (int32 i = 0; i < fCount; i++) {
// find the buffer id, and reclaim it in all groups it belongs to // find the buffer id, and reclaim it in all groups it belongs to
if (info[i].id == id) { if (fInfos[i].id == id) {
reclaimed_count++; reclaimedCount++;
if (info[i].reclaimed) { if (fInfos[i].reclaimed) {
ERROR("_shared_buffer_list::RecycleBuffer, BBuffer %p, id = %ld already reclaimed\n", buffer, id); ERROR("SharedBufferList::RecycleBuffer, BBuffer %p, id = %ld "
"already reclaimed\n", buffer, id);
DEBUG_ONLY(debugger("buffer already reclaimed")); DEBUG_ONLY(debugger("buffer already reclaimed"));
continue; continue;
} }
info[i].reclaimed = true; fInfos[i].reclaimed = true;
release_sem_etc(info[i].reclaim_sem, 1, B_DO_NOT_RESCHEDULE); release_sem_etc(fInfos[i].reclaim_sem, 1, B_DO_NOT_RESCHEDULE);
} }
} }
if (Unlock() != B_OK) if (Unlock() != B_OK)
return B_ERROR; return B_ERROR;
if (reclaimed_count == 0) { if (reclaimedCount == 0) {
ERROR("shared_buffer_list::RecycleBuffer, BBuffer %p, id = %ld NOT reclaimed\n", buffer, id); ERROR("shared_buffer_list::RecycleBuffer, BBuffer %p, id = %ld NOT "
"reclaimed\n", buffer, id);
return B_ERROR; return B_ERROR;
} }
return B_OK; return B_OK;
} }
/*! Returns exactly \a bufferCount buffers from the group specified via its
\a groupReclaimSem if successful.
*/
status_t status_t
_shared_buffer_list::GetBufferList(sem_id group_reclaim_sem, int32 buf_count, BBuffer **out_buffers) SharedBufferList::GetBufferList(sem_id groupReclaimSem, int32 bufferCount,
BBuffer** buffers)
{ {
CALLED(); CALLED();
int32 found;
found = 0;
if (Lock() != B_OK) if (Lock() != B_OK)
return B_ERROR; return B_ERROR;
for (int32 i = 0; i < buffercount; i++) int32 found = 0;
if (info[i].reclaim_sem == group_reclaim_sem) {
out_buffers[found++] = info[i].buffer; for (int32 i = 0; i < fCount; i++)
if (found == buf_count) if (fInfos[i].reclaim_sem == groupReclaimSem) {
buffers[found++] = fInfos[i].buffer;
if (found == bufferCount)
break; break;
} }
if (Unlock() != B_OK) if (Unlock() != B_OK)
return B_ERROR; return B_ERROR;
return (found == buf_count) ? B_OK : B_ERROR; return found == bufferCount ? B_OK : B_ERROR;
} }
status_t
SharedBufferList::_Init()
{
CALLED();
fSemaphore = create_sem(0, "shared buffer list lock");
if (fSemaphore < 0)
return fSemaphore;
fAtom = 0;
for (int32 i = 0; i < kMaxBuffers; i++) {
fInfos[i].id = -1;
}
return B_OK;
}
/*! Used by RequestBuffer, call this one with the list locked!
*/
void
SharedBufferList::_RequestBufferInOtherGroups(sem_id groupReclaimSem,
media_buffer_id id)
{
for (int32 i = 0; i < fCount; i++) {
// find buffers with same id, but belonging to other groups
if (fInfos[i].id == id && fInfos[i].reclaim_sem != groupReclaimSem) {
// and mark them as requested
// TODO: this can deadlock if BBuffers with same media_buffer_id
// exist in more than one BBufferGroup, and RequestBuffer()
// is called on both groups (which should not be done).
status_t status;
do {
status = acquire_sem(fInfos[i].reclaim_sem);
} while (status == B_INTERRUPTED);
// try to skip entries that belong to crashed teams
if (status != B_OK)
continue;
if (fInfos[i].reclaimed == false) {
ERROR("SharedBufferList:: RequestBufferInOtherGroups BBuffer "
"%p, id = %ld not reclaimed while requesting\n",
fInfos[i].buffer, id);
continue;
}
fInfos[i].reclaimed = false;
}
}
}
} // namespace BPrivate
+41 -26
View File
@@ -15,24 +15,26 @@
BufferManager::BufferManager() BufferManager::BufferManager()
: :
fSharedBufferList(_shared_buffer_list::Clone()), fSharedBufferList(NULL),
fSharedBufferListArea(-1),
fNextBufferID(1), fNextBufferID(1),
fLocker("buffer manager locker") fLocker("buffer manager locker")
{ {
fSharedBufferListID = area_for(fSharedBufferList); fSharedBufferListArea
= BPrivate::SharedBufferList::Create(&fSharedBufferList);
} }
BufferManager::~BufferManager() BufferManager::~BufferManager()
{ {
fSharedBufferList->Unmap(); fSharedBufferList->Put();
} }
area_id area_id
BufferManager::SharedBufferListID() BufferManager::SharedBufferListArea()
{ {
return fSharedBufferListID; return fSharedBufferListArea;
} }
@@ -84,14 +86,19 @@ BufferManager::RegisterBuffer(team_id team, size_t size, int32 flags,
info.offset = offset; info.offset = offset;
info.size = size; info.size = size;
info.flags = flags; info.flags = flags;
info.teams.insert(team);
*_bufferID = info.id; try {
info.teams.insert(team);
fBufferInfoMap.Put(info.id, info); if (fBufferInfoMap.Put(info.id, info) != B_OK)
throw std::bad_alloc();
} catch (std::bad_alloc& exception) {
_ReleaseClonedArea(clonedArea);
return B_NO_MEMORY;
}
TRACE("RegisterBuffer: done, bufferID = %ld\n", info.id); TRACE("RegisterBuffer: done, bufferID = %ld\n", info.id);
*_bufferID = info.id;
return B_OK; return B_OK;
} }
@@ -100,12 +107,12 @@ status_t
BufferManager::UnregisterBuffer(team_id team, media_buffer_id bufferID) BufferManager::UnregisterBuffer(team_id team, media_buffer_id bufferID)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
TRACE("UnregisterBuffer: team = %ld, bufferid = %ld\n", team, bufferID); TRACE("UnregisterBuffer: team = %ld, bufferID = %ld\n", team, bufferID);
buffer_info* info; buffer_info* info;
if (!fBufferInfoMap.Get(bufferID, info)) { if (!fBufferInfoMap.Get(bufferID, info)) {
ERROR("UnregisterBuffer: failed to unregister buffer! team = %ld, " ERROR("UnregisterBuffer: failed to unregister buffer! team = %ld, "
"bufferid = %ld\n", team, bufferID); "bufferID = %ld\n", team, bufferID);
return B_ERROR; return B_ERROR;
} }
@@ -146,7 +153,7 @@ BufferManager::CleanupTeam(team_id team)
if (entry.value.teams.empty()) { if (entry.value.teams.empty()) {
PRINT(1, "BufferManager::CleanupTeam: removing buffer id %ld that " PRINT(1, "BufferManager::CleanupTeam: removing buffer id %ld that "
"has no teams\n", entry.key); "has no teams\n", entry.key.GetHashCode());
_ReleaseClonedArea(entry.value.area); _ReleaseClonedArea(entry.value.area);
iterator.Remove(); iterator.Remove();
} }
@@ -182,14 +189,16 @@ BufferManager::Dump()
area_id area_id
BufferManager::_CloneArea(area_id area) BufferManager::_CloneArea(area_id area)
{ {
clone_info* info; {
if (fCloneInfoMap.Get(area, info)) { clone_info* info;
// we have already cloned this particular area if (fCloneInfoMap.Get(area, info)) {
TRACE("BufferManager::_CloneArea() area %ld has already been cloned " // we have already cloned this particular area
"(id %ld)\n", area, info->clone); TRACE("BufferManager::_CloneArea() area %ld has already been "
"cloned (id %ld)\n", area, info->clone);
info->ref_count++; info->ref_count++;
return info->clone; return info->clone;
}
} }
void* address; void* address;
@@ -199,16 +208,22 @@ BufferManager::_CloneArea(area_id area)
TRACE("BufferManager::_CloneArea() cloned area %ld, clone id %ld\n", TRACE("BufferManager::_CloneArea() cloned area %ld, clone id %ld\n",
area, clonedArea); area, clonedArea);
if (clonedArea >= 0) { if (clonedArea < 0)
clone_info info; return clonedArea;
info.clone = clonedArea;
info.ref_count = 1;
fCloneInfoMap.Put(area, info); clone_info info;
fSourceInfoMap.Put(clonedArea, area); info.clone = clonedArea;
info.ref_count = 1;
if (fCloneInfoMap.Put(area, info) == B_OK) {
if (fSourceInfoMap.Put(clonedArea, area) == B_OK)
return clonedArea;
fCloneInfoMap.Remove(area);
} }
return clonedArea; delete_area(clonedArea);
return B_NO_MEMORY;
} }
+6 -4
View File
@@ -13,7 +13,9 @@
#include <HashMap.h> #include <HashMap.h>
struct _shared_buffer_list; namespace BPrivate {
class SharedBufferList;
}
class BufferManager { class BufferManager {
@@ -21,7 +23,7 @@ public:
BufferManager(); BufferManager();
~BufferManager(); ~BufferManager();
area_id SharedBufferListID(); area_id SharedBufferListArea();
status_t RegisterBuffer(team_id team, status_t RegisterBuffer(team_id team,
media_buffer_id bufferID, size_t* _size, media_buffer_id bufferID, size_t* _size,
@@ -99,8 +101,8 @@ private:
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; typedef HashMap<id_hash<area_id>, area_id> SourceInfoMap;
_shared_buffer_list* fSharedBufferList; BPrivate::SharedBufferList* fSharedBufferList;
area_id fSharedBufferListID; area_id fSharedBufferListArea;
media_buffer_id fNextBufferID; media_buffer_id fNextBufferID;
BLocker fLocker; BLocker fLocker;
BufferInfoMap fBufferInfoMap; BufferInfoMap fBufferInfoMap;
+6 -2
View File
@@ -2,6 +2,10 @@
* Copyright 2002, 2003 Marcus Overhagen, Jérôme Duval. All rights reserved. * Copyright 2002, 2003 Marcus Overhagen, Jérôme Duval. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "DefaultManager.h"
#include <Application.h> #include <Application.h>
#include <Directory.h> #include <Directory.h>
#include <File.h> #include <File.h>
@@ -12,7 +16,7 @@
#include <Path.h> #include <Path.h>
#include <TimeSource.h> #include <TimeSource.h>
#include <string.h> #include <string.h>
#include "DefaultManager.h"
#include "DormantNodeManager.h" #include "DormantNodeManager.h"
#include "NodeManager.h" #include "NodeManager.h"
#include "debug.h" #include "debug.h"
@@ -132,7 +136,7 @@ DefaultManager::SaveState(NodeManager *node_manager)
dormant_node_info info; dormant_node_info info;
media_node node; media_node node;
entry_ref ref; entry_ref ref;
if (node_manager->GetCloneForId(&node, media_node_ids[i], be_app->Team()) != B_OK) if (node_manager->GetCloneForID(&node, media_node_ids[i], be_app->Team()) != B_OK)
continue; continue;
if (node_manager->GetDormantNodeInfo(&info, node) != B_OK) if (node_manager->GetDormantNodeInfo(&info, node) != B_OK)
continue; continue;
+48 -39
View File
@@ -77,7 +77,7 @@ NodeManager::RegisterNode(media_node_id *nodeid, media_addon_id addon_id, int32
BAutolock lock(fLocker); BAutolock lock(fLocker);
bool b; bool b;
registered_node rn; registered_node rn;
rn.nodeid = fNextNodeID; rn.node_id = fNextNodeID;
rn.addon_id = addon_id; rn.addon_id = addon_id;
rn.addon_flavor_id = addon_flavor_id; rn.addon_flavor_id = addon_flavor_id;
strcpy(rn.name, name); strcpy(rn.name, name);
@@ -253,40 +253,45 @@ NodeManager::FinalReleaseNode(media_node_id nodeid)
status_t status_t
NodeManager::GetCloneForId(media_node *node, media_node_id nodeid, team_id team) NodeManager::GetCloneForID(media_node* node, media_node_id nodeID, team_id team)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
registered_node *rn; TRACE("NodeManager::GetCloneForID enter: node %ld team %ld\n", nodeID,
bool b; team);
TRACE("NodeManager::GetCloneForId enter: node %ld team %ld\n", nodeid, team);
if (B_OK != IncrementGlobalRefCount(nodeid, team)) { if (IncrementGlobalRefCount(nodeID, team) != B_OK) {
ERROR("NodeManager::GetCloneForId: couldn't increment ref count, node %ld team %ld\n", nodeid, team); ERROR("NodeManager::GetCloneForID: couldn't increment ref count, "
"node %ld team %ld\n", nodeID, team);
return B_ERROR; return B_ERROR;
} }
b = fRegisteredNodeMap->Get(nodeid, &rn); registered_node* registeredNode;
if (!b) { if (!fRegisteredNodeMap->Get(nodeID, &registeredNode)) {
ERROR("NodeManager::GetCloneForId: node %ld not found\n", nodeid); ERROR("NodeManager::GetCloneForID: node %ld not found\n", nodeID);
DecrementGlobalRefCount(nodeid, team); DecrementGlobalRefCount(nodeID, team);
return B_ERROR; return B_ERROR;
} }
node->node = rn->nodeid; node->node = registeredNode->node_id;
node->port = rn->port; node->port = registeredNode->port;
node->kind = rn->kinds; node->kind = registeredNode->kinds;
TRACE("NodeManager::GetCloneForId leave: node %ld team %ld\n", nodeid, team); TRACE("NodeManager::GetCloneForID leave: node %ld team %ld\n", nodeID,
team);
return B_OK; return B_OK;
} }
/* This function locates the default "node" for the requested "type" and returnes a clone. /*! This function locates the default "node" for the requested "type" and
* If the requested type is AUDIO_OUTPUT_EX, also "input_name" and "input_id" need to be set and returned, returns a clone.
* as this is required by BMediaRoster::GetAudioOutput(media_node *out_node, int32 *out_input_id, BString *out_input_name) If the requested type is AUDIO_OUTPUT_EX, also "input_name" and "input_id"
*/ need to be set and returned, as this is required by
BMediaRoster::GetAudioOutput(media_node *out_node, int32 *out_input_id,
BString *out_input_name).
*/
status_t status_t
NodeManager::GetClone(media_node *node, char *input_name, int32 *input_id, node_type type, team_id team) NodeManager::GetClone(media_node *node, char *input_name, int32 *input_id,
node_type type, team_id team)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
status_t status; status_t status;
@@ -302,9 +307,9 @@ NodeManager::GetClone(media_node *node, char *input_name, int32 *input_id, node_
} }
ASSERT(id > 0); ASSERT(id > 0);
status = GetCloneForId(node, id, team); status = GetCloneForID(node, id, team);
if (status != B_OK) { if (status != B_OK) {
ERROR("NodeManager::GetClone: couldn't GetCloneForId, id %ld, team %ld, type %d (%s)\n", id, team, type, get_node_type(type)); ERROR("NodeManager::GetClone: couldn't GetCloneForID, id %ld, team %ld, type %d (%s)\n", id, team, type, get_node_type(type));
*node = media_node::null; *node = media_node::null;
return status; return status;
} }
@@ -366,37 +371,39 @@ NodeManager::PublishOutputs(const media_node &node, const media_output *outputs,
status_t status_t
NodeManager::FindNodeId(media_node_id *nodeid, port_id port) NodeManager::FindNodeID(media_node_id* nodeID, port_id port)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
registered_node *rn; registered_node *rn;
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) { for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
if (rn->port == port) { if (rn->port == port) {
*nodeid = rn->nodeid; *nodeID = rn->node_id;
TRACE("NodeManager::FindNodeId found port %ld, node %ld\n", port, *nodeid); TRACE("NodeManager::FindNodeID found port %ld, node %ld\n", port,
*nodeID);
return B_OK; return B_OK;
} }
media_output *output; media_output *output;
for (rn->outputlist.Rewind(); rn->outputlist.GetNext(&output); ) { for (rn->outputlist.Rewind(); rn->outputlist.GetNext(&output); ) {
if (output->source.port == port) { if (output->source.port == port) {
*nodeid = rn->nodeid; *nodeID = rn->node_id;
TRACE("NodeManager::FindNodeId found output port %ld, node %ld\n", port, *nodeid); TRACE("NodeManager::FindNodeID found output port %ld, node %ld\n", port, *nodeid);
return B_OK; return B_OK;
} }
} }
media_input *input; media_input *input;
for (rn->inputlist.Rewind(); rn->inputlist.GetNext(&input); ) { for (rn->inputlist.Rewind(); rn->inputlist.GetNext(&input); ) {
if (input->destination.port == port) { if (input->destination.port == port) {
*nodeid = rn->nodeid; *nodeID = rn->node_id;
TRACE("NodeManager::FindNodeId found input port %ld, node %ld\n", port, *nodeid); TRACE("NodeManager::FindNodeID found input port %ld, node %ld\n", port, *nodeid);
return B_OK; return B_OK;
} }
} }
} }
ERROR("NodeManager::FindNodeId failed, port %ld\n", port); ERROR("NodeManager::FindNodeID failed, port %ld\n", port);
return B_ERROR; return B_ERROR;
} }
status_t status_t
NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node &node) NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node &node)
{ {
@@ -404,7 +411,7 @@ NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node &
// XXX not sure if this is correct // XXX not sure if this is correct
registered_node *rn; registered_node *rn;
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) { for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
if (rn->nodeid == node.node) { if (rn->node_id == node.node) {
if (rn->addon_id == -1 && node.node != NODE_SYSTEM_TIMESOURCE_ID) { // This function must return an error if the node is application owned if (rn->addon_id == -1 && node.node != NODE_SYSTEM_TIMESOURCE_ID) { // This function must return an error if the node is application owned
TRACE("NodeManager::GetDormantNodeInfo NODE IS APPLICATION OWNED! node %ld, addon_id %ld, addon_flavor_id %ld, name \"%s\"\n", node.node, rn->addon_id, rn->addon_flavor_id, rn->name); TRACE("NodeManager::GetDormantNodeInfo NODE IS APPLICATION OWNED! node %ld, addon_id %ld, addon_flavor_id %ld, name \"%s\"\n", node.node, rn->addon_id, rn->addon_flavor_id, rn->name);
return B_ERROR; return B_ERROR;
@@ -422,13 +429,14 @@ NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node &
return B_ERROR; return B_ERROR;
} }
status_t status_t
NodeManager::GetLiveNodeInfo(live_node_info *live_info, const media_node &node) NodeManager::GetLiveNodeInfo(live_node_info *live_info, const media_node &node)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
registered_node *rn; registered_node *rn;
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) { for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
if (rn->nodeid == node.node) { if (rn->node_id == node.node) {
ASSERT(node.port == rn->port); ASSERT(node.port == rn->port);
ASSERT((node.kind & NODE_KIND_COMPARE_MASK) == (rn->kinds & NODE_KIND_COMPARE_MASK)); ASSERT((node.kind & NODE_KIND_COMPARE_MASK) == (rn->kinds & NODE_KIND_COMPARE_MASK));
live_info->node = node; live_info->node = node;
@@ -451,7 +459,7 @@ NodeManager::GetInstances(media_node_id *node_ids, int32* count, int32 maxcount,
*count = 0; *count = 0;
for (fRegisteredNodeMap->Rewind(); (maxcount > 0) && fRegisteredNodeMap->GetNext(&rn); ) { for (fRegisteredNodeMap->Rewind(); (maxcount > 0) && fRegisteredNodeMap->GetNext(&rn); ) {
if (rn->addon_id == addon_id && rn->addon_flavor_id == addon_flavor_id) { if (rn->addon_id == addon_id && rn->addon_flavor_id == addon_flavor_id) {
node_ids[*count] = rn->nodeid; node_ids[*count] = rn->node_id;
*count += 1; *count += 1;
maxcount -= 1; maxcount -= 1;
} }
@@ -513,7 +521,7 @@ NodeManager::GetLiveNodes(Stack<live_node_info> *livenodes, int32 maxcount, cons
} }
live_node_info lni; live_node_info lni;
lni.node.node = rn->nodeid; lni.node.node = rn->node_id;
lni.node.port = rn->port; lni.node.port = rn->port;
lni.node.kind = rn->kinds; lni.node.kind = rn->kinds;
lni.hint_point = BPoint(0, 0); lni.hint_point = BPoint(0, 0);
@@ -526,16 +534,17 @@ NodeManager::GetLiveNodes(Stack<live_node_info> *livenodes, int32 maxcount, cons
return B_OK; return B_OK;
} }
/* Add media_node_id of all live nodes to the message
* int32 "media_node_id" (multiple items) /*! Add media_node_id of all live nodes to the message
*/ int32 "media_node_id" (multiple items)
*/
status_t status_t
NodeManager::GetLiveNodes(BMessage *msg) NodeManager::GetLiveNodes(BMessage *msg)
{ {
BAutolock lock(fLocker); BAutolock lock(fLocker);
registered_node *rn; registered_node *rn;
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) { for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
msg->AddInt32("media_node_id", rn->nodeid); msg->AddInt32("media_node_id", rn->node_id);
} }
return B_OK; return B_OK;
} }
@@ -966,7 +975,7 @@ NodeManager::Dump()
registered_node *rn; registered_node *rn;
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) { for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
printf(" node-id %ld, addon-id %ld, addon-flavor-id %ld, port %ld, creator %ld, team %ld, kinds %#08Lx, name \"%s\"\n", printf(" node-id %ld, addon-id %ld, addon-flavor-id %ld, port %ld, creator %ld, team %ld, kinds %#08Lx, name \"%s\"\n",
rn->nodeid, rn->addon_id, rn->addon_flavor_id, rn->port, rn->creator, rn->team, rn->kinds, rn->name); rn->node_id, rn->addon_id, rn->addon_flavor_id, rn->port, rn->creator, rn->team, rn->kinds, rn->name);
printf(" teams (refcount): "); printf(" teams (refcount): ");
team_id *team; team_id *team;
int32 *refcount; int32 *refcount;
+5 -4
View File
@@ -10,7 +10,7 @@
struct registered_node { struct registered_node {
media_node_id nodeid; media_node_id node_id;
media_addon_id addon_id; media_addon_id addon_id;
int32 addon_flavor_id; int32 addon_flavor_id;
char name[B_MEDIA_NAME_LENGTH]; char name[B_MEDIA_NAME_LENGTH];
@@ -52,18 +52,19 @@ public:
/* Management of system wide default nodes */ /* Management of system wide default nodes */
status_t SetDefaultNode(node_type type, const media_node *node, const dormant_node_info *info, const media_input *input); status_t SetDefaultNode(node_type type, const media_node *node, const dormant_node_info *info, const media_input *input);
status_t GetDefaultNode(media_node_id *nodeid, char *input_name, int32 *input_id, node_type type); status_t GetDefaultNode(media_node_id* nodeID, char* name, int32* id,
node_type type);
status_t RescanDefaultNodes(); status_t RescanDefaultNodes();
/* Management of live nodes */ /* Management of live nodes */
status_t RegisterNode(media_node_id *nodeid, media_addon_id addon_id, int32 addon_flavor_id, const char *name, uint64 kinds, port_id port, team_id team); status_t RegisterNode(media_node_id *nodeid, media_addon_id addon_id, int32 addon_flavor_id, const char *name, uint64 kinds, port_id port, team_id team);
status_t UnregisterNode(media_addon_id *addonid, int32 *flavorid, media_node_id nodeid, team_id team); status_t UnregisterNode(media_addon_id *addonid, int32 *flavorid, media_node_id nodeid, team_id team);
status_t GetCloneForId(media_node *node, media_node_id nodeid, team_id team); status_t GetCloneForID(media_node* node, media_node_id nodeID, team_id team);
status_t GetClone(media_node *node, char *input_name, int32 *input_id, node_type type, team_id team); status_t GetClone(media_node *node, char *input_name, int32 *input_id, node_type type, team_id team);
status_t ReleaseNode(const media_node &node, team_id team); status_t ReleaseNode(const media_node &node, team_id team);
status_t PublishInputs(const media_node &node, const media_input *inputs, int32 count); status_t PublishInputs(const media_node &node, const media_input *inputs, int32 count);
status_t PublishOutputs(const media_node &node, const media_output *outputs, int32 count); status_t PublishOutputs(const media_node &node, const media_output *outputs, int32 count);
status_t FindNodeId(media_node_id *nodeid, port_id port); status_t FindNodeID(media_node_id* nodeID, port_id port);
status_t GetLiveNodeInfo(live_node_info *live_info, const media_node &node); status_t GetLiveNodeInfo(live_node_info *live_info, const media_node &node);
status_t GetInstances(media_node_id *node_ids, int32* count, int32 maxcount, media_addon_id addon_id, int32 addon_flavor_id); status_t GetInstances(media_node_id *node_ids, int32* count, int32 maxcount, media_addon_id addon_id, int32 addon_flavor_id);
status_t GetLiveNodes(Stack<live_node_info> *livenodes, int32 maxcount, const media_format *inputformat = NULL, const media_format *outputformat = NULL, const char* name = NULL, uint64 require_kinds = 0); status_t GetLiveNodes(Stack<live_node_info> *livenodes, int32 maxcount, const media_format *inputformat = NULL, const media_format *outputformat = NULL, const char* name = NULL, uint64 require_kinds = 0);
-63
View File
@@ -1,63 +0,0 @@
#ifndef _SERVER_INTERFACE_H_
#define _SERVER_INTERFACE_H_
#include <MediaDefs.h>
#include <MediaNode.h>
#include <MediaAddOn.h>
#include <Entry.h>
enum {
ADDONSERVER_INSTANTIATE_DORMANT_NODE,
SERVER_REGISTER_MEDIAADDON,
SERVER_UNREGISTER_MEDIAADDON,
SERVER_GET_MEDIAADDON_REF,
SERVER_REGISTER_DORMANT_NODE,
SERVER_GET_DORMANT_NODES,
SERVER_GET_DORMANT_FLAVOR_INFO,
END
};
struct xfer_server_get_dormant_flavor_info
{
media_addon_id addon;
int32 flavor_id;
port_id reply_port;
};
struct xfer_server_get_dormant_flavor_info_reply
{
status_t result;
type_code dfi_type; // the flatten type_code
size_t dfi_size;
char dfi[1]; // a flattened dormant_flavor_info, dfi_size large
};
struct xfer_server_get_dormant_nodes
{
int32 maxcount;
bool has_input;
media_format inputformat;
bool has_output;
media_format outputformat;
bool has_name;
char name[B_MEDIA_NAME_LENGTH + 1]; // 1 for a trailing "*"
uint64 require_kinds;
uint64 deny_kinds;
port_id reply_port;
};
struct xfer_server_get_dormant_nodes_reply
{
status_t result;
int32 count; // if count > 0, a second reply containing count dormant_node_infos is send
};
struct xfer_server_register_dormant_node
{
media_addon_id purge_id; // if > 0, server must first remove all dormant_flavor_infos belonging to that id
type_code dfi_type; // the flatten type_code
size_t dfi_size;
char dfi[1]; // a flattened dormant_flavor_info, dfi_size large
};
#endif
+69 -58
View File
@@ -27,10 +27,15 @@
* *
*/ */
/* to comply with the license above, do not remove the following line */ /* to comply with the license above, do not remove the following line */
char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 " char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 "
"Marcus Overhagen <[email protected]>"; "Marcus Overhagen <[email protected]>";
#include <stdio.h>
#include <string.h>
#include <Alert.h> #include <Alert.h>
#include <Application.h> #include <Application.h>
#include <Autolock.h> #include <Autolock.h>
@@ -40,9 +45,6 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 "
#include <MediaFormats.h> #include <MediaFormats.h>
#include <Messenger.h> #include <Messenger.h>
#include <stdio.h>
#include <string.h>
#include "AddOnManager.h" #include "AddOnManager.h"
#include "AppManager.h" #include "AppManager.h"
#include "BufferManager.h" #include "BufferManager.h"
@@ -56,12 +58,6 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 "
#include "debug.h" #include "debug.h"
#include "media_server.h" #include "media_server.h"
/*
*
* An implementation of a new media_server for the OpenBeOS MediaKit
* Started by Marcus Overhagen <marcus@overhagen.de> on 2001-10-25
*
*/
AddOnManager * gAddOnManager; AddOnManager * gAddOnManager;
AppManager * gAppManager; AppManager * gAppManager;
@@ -310,10 +306,10 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
ASSERT(request->delta == 1 || request->delta == -1); ASSERT(request->delta == 1 || request->delta == -1);
if (request->delta == 1) { if (request->delta == 1) {
rv = gNodeManager->IncrementAddonFlavorInstancesCount( rv = gNodeManager->IncrementAddonFlavorInstancesCount(
request->addonid, request->flavorid, request->team); request->addon_id, request->flavor_id, request->team);
} else { } else {
rv = gNodeManager->DecrementAddonFlavorInstancesCount( rv = gNodeManager->DecrementAddonFlavorInstancesCount(
request->addonid, request->flavorid, request->team); request->addon_id, request->flavor_id, request->team);
} }
request->SendReply(rv, &reply, sizeof(reply)); request->SendReply(rv, &reply, sizeof(reply));
break; break;
@@ -352,7 +348,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
= (server_get_mediaaddon_ref_request *)data; = (server_get_mediaaddon_ref_request *)data;
server_get_mediaaddon_ref_reply reply; server_get_mediaaddon_ref_reply reply;
entry_ref tempref; entry_ref tempref;
reply.result = gNodeManager->GetAddonRef(&tempref, msg->addonid); reply.result = gNodeManager->GetAddonRef(&tempref, msg->addon_id);
reply.ref = tempref; reply.ref = tempref;
write_port(msg->reply_port, 0, &reply, sizeof(reply)); write_port(msg->reply_port, 0, &reply, sizeof(reply));
break; break;
@@ -363,7 +359,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
const server_node_id_for_request *request const server_node_id_for_request *request
= reinterpret_cast<const server_node_id_for_request *>(data); = reinterpret_cast<const server_node_id_for_request *>(data);
server_node_id_for_reply reply; server_node_id_for_reply reply;
rv = gNodeManager->FindNodeId(&reply.nodeid, request->port); rv = gNodeManager->FindNodeID(&reply.node_id, request->port);
request->SendReply(rv, &reply, sizeof(reply)); request->SendReply(rv, &reply, sizeof(reply));
break; break;
} }
@@ -432,7 +428,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
const server_get_node_for_request *request const server_get_node_for_request *request
= reinterpret_cast<const server_get_node_for_request *>(data); = reinterpret_cast<const server_get_node_for_request *>(data);
server_get_node_for_reply reply; server_get_node_for_reply reply;
rv = gNodeManager->GetCloneForId(&reply.clone, request->nodeid, rv = gNodeManager->GetCloneForID(&reply.clone, request->node_id,
request->team); request->team);
request->SendReply(rv, &reply, sizeof(reply)); request->SendReply(rv, &reply, sizeof(reply));
break; break;
@@ -453,7 +449,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
const server_register_node_request *request const server_register_node_request *request
= reinterpret_cast<const server_register_node_request *>(data); = reinterpret_cast<const server_register_node_request *>(data);
server_register_node_reply reply; server_register_node_reply reply;
rv = gNodeManager->RegisterNode(&reply.nodeid, request->addon_id, rv = gNodeManager->RegisterNode(&reply.node_id, request->addon_id,
request->addon_flavor_id, request->name, request->kinds, request->addon_flavor_id, request->name, request->kinds,
request->port, request->team); request->port, request->team);
request->SendReply(rv, &reply, sizeof(reply)); request->SendReply(rv, &reply, sizeof(reply));
@@ -466,8 +462,8 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
= reinterpret_cast<const server_unregister_node_request *>( = reinterpret_cast<const server_unregister_node_request *>(
data); data);
server_unregister_node_reply reply; server_unregister_node_reply reply;
rv = gNodeManager->UnregisterNode(&reply.addonid, &reply.flavorid, rv = gNodeManager->UnregisterNode(&reply.addon_id, &reply.flavor_id,
request->nodeid, request->team); request->node_id, request->team);
request->SendReply(rv, &reply, sizeof(reply)); request->SendReply(rv, &reply, sizeof(reply));
break; break;
} }
@@ -588,7 +584,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
server_register_mediaaddon_request *msg server_register_mediaaddon_request *msg
= (server_register_mediaaddon_request *)data; = (server_register_mediaaddon_request *)data;
server_register_mediaaddon_reply reply; server_register_mediaaddon_reply reply;
gNodeManager->RegisterAddon(msg->ref, &reply.addonid); gNodeManager->RegisterAddon(msg->ref, &reply.addon_id);
write_port(msg->reply_port, 0, &reply, sizeof(reply)); write_port(msg->reply_port, 0, &reply, sizeof(reply));
break; break;
} }
@@ -597,20 +593,22 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
{ {
server_unregister_mediaaddon_command *msg server_unregister_mediaaddon_command *msg
= (server_unregister_mediaaddon_command *)data; = (server_unregister_mediaaddon_command *)data;
gNodeManager->UnregisterAddon(msg->addonid); gNodeManager->UnregisterAddon(msg->addon_id);
break; break;
} }
case SERVER_REGISTER_DORMANT_NODE: case SERVER_REGISTER_DORMANT_NODE:
{ {
xfer_server_register_dormant_node *msg xfer_server_register_dormant_node* msg
= (xfer_server_register_dormant_node *)data; = (xfer_server_register_dormant_node*)data;
dormant_flavor_info dfi;
if (msg->purge_id > 0) if (msg->purge_id > 0)
gNodeManager->InvalidateDormantFlavorInfo(msg->purge_id); gNodeManager->InvalidateDormantFlavorInfo(msg->purge_id);
rv = dfi.Unflatten(msg->dfi_type, &(msg->dfi), msg->dfi_size);
ASSERT(rv == B_OK); dormant_flavor_info dormantFlavorInfo;
gNodeManager->AddDormantFlavorInfo(dfi); status_t status = dormantFlavorInfo.Unflatten(msg->type,
msg->flattened_data, msg->flattened_size);
if (status == B_OK)
gNodeManager->AddDormantFlavorInfo(dormantFlavorInfo);
break; break;
} }
@@ -618,24 +616,29 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
{ {
xfer_server_get_dormant_nodes *msg xfer_server_get_dormant_nodes *msg
= (xfer_server_get_dormant_nodes *)data; = (xfer_server_get_dormant_nodes *)data;
xfer_server_get_dormant_nodes_reply reply; xfer_server_get_dormant_nodes_reply reply;
dormant_node_info * infos = new dormant_node_info[msg->maxcount]; reply.count = msg->max_count;
reply.count = msg->maxcount;
reply.result = gNodeManager->GetDormantNodes( dormant_node_info* infos
infos, = new(std::nothrow) dormant_node_info[reply.count];
&reply.count, if (infos != NULL) {
msg->has_input ? &msg->inputformat : NULL, reply.result = gNodeManager->GetDormantNodes(infos,
msg->has_output ? &msg->outputformat : NULL, &reply.count, msg->has_input ? &msg->input_format : NULL,
msg->has_name ? msg->name : NULL, msg->has_output ? &msg->output_format : NULL,
msg->require_kinds, msg->has_name ? msg->name : NULL, msg->require_kinds,
msg->deny_kinds); msg->deny_kinds);
} else
reply.result = B_NO_MEMORY;
if (reply.result != B_OK) if (reply.result != B_OK)
reply.count = 0; reply.count = 0;
write_port(msg->reply_port, 0, &reply, sizeof(reply)); write_port(msg->reply_port, 0, &reply, sizeof(reply));
if (reply.count > 0) if (reply.count > 0) {
write_port(msg->reply_port, 0, infos, reply.count write_port(msg->reply_port, 0, infos,
* sizeof(dormant_node_info)); reply.count * sizeof(dormant_node_info));
delete [] infos; }
delete[] infos;
break; break;
} }
@@ -643,40 +646,48 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
{ {
xfer_server_get_dormant_flavor_info *msg xfer_server_get_dormant_flavor_info *msg
= (xfer_server_get_dormant_flavor_info *)data; = (xfer_server_get_dormant_flavor_info *)data;
dormant_flavor_info dfi; dormant_flavor_info dormantFlavorInfo;
status_t rv; status_t rv;
rv = gNodeManager->GetDormantFlavorInfoFor(msg->addon, rv = gNodeManager->GetDormantFlavorInfoFor(msg->addon,
msg->flavor_id, &dfi); msg->flavor_id, &dormantFlavorInfo);
if (rv != B_OK) { if (rv != B_OK) {
xfer_server_get_dormant_flavor_info_reply reply; xfer_server_get_dormant_flavor_info_reply reply;
reply.result = rv; reply.result = rv;
write_port(msg->reply_port, 0, &reply, sizeof(reply)); write_port(msg->reply_port, 0, &reply, sizeof(reply));
} else { } else {
xfer_server_get_dormant_flavor_info_reply *reply; size_t replySize
int replysize; = sizeof(xfer_server_get_dormant_flavor_info_reply)
replysize = sizeof(xfer_server_get_dormant_flavor_info_reply) + dormantFlavorInfo.FlattenedSize();
+ dfi.FlattenedSize(); xfer_server_get_dormant_flavor_info_reply* reply
reply = (xfer_server_get_dormant_flavor_info_reply *)malloc( = (xfer_server_get_dormant_flavor_info_reply*)malloc(
replysize); replySize);
if (reply != NULL) {
reply->type = dormantFlavorInfo.TypeCode();
reply->flattened_size = dormantFlavorInfo.FlattenedSize();
reply->result = dormantFlavorInfo.Flatten(
reply->flattened_data, reply->flattened_size);
reply->dfi_size = dfi.FlattenedSize(); write_port(msg->reply_port, 0, reply, replySize);
reply->dfi_type = dfi.TypeCode(); free(reply);
reply->result = dfi.Flatten(reply->dfi, reply->dfi_size); } else {
write_port(msg->reply_port, 0, reply, replysize); xfer_server_get_dormant_flavor_info_reply reply;
free(reply); reply.result = B_NO_MEMORY;
write_port(msg->reply_port, 0, &reply, sizeof(reply));
}
} }
break; break;
} }
case SERVER_SET_NODE_CREATOR: case SERVER_SET_NODE_CREATOR:
{ {
const server_set_node_creator_request *request const server_set_node_creator_request* request
= reinterpret_cast<const server_set_node_creator_request *>( = reinterpret_cast<const server_set_node_creator_request*>(
data); data);
server_set_node_creator_reply reply; server_set_node_creator_reply reply;
rv = gNodeManager->SetNodeCreator(request->node, request->creator); status_t status = gNodeManager->SetNodeCreator(request->node,
request->SendReply(rv, &reply, sizeof(reply)); request->creator);
request->SendReply(status, &reply, sizeof(reply));
break; break;
} }
@@ -687,7 +698,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
const server_get_shared_buffer_area_request *>(data); const server_get_shared_buffer_area_request *>(data);
server_get_shared_buffer_area_reply reply; server_get_shared_buffer_area_reply reply;
reply.area = gBufferManager->SharedBufferListID(); reply.area = gBufferManager->SharedBufferListArea();
request->SendReply(B_OK, &reply, sizeof(reply)); request->SendReply(B_OK, &reply, sizeof(reply));
break; break;
} }
@@ -722,7 +733,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
const server_unregister_buffer_command *cmd = reinterpret_cast< const server_unregister_buffer_command *cmd = reinterpret_cast<
const server_unregister_buffer_command *>(data); const server_unregister_buffer_command *>(data);
gBufferManager->UnregisterBuffer(cmd->team, cmd->bufferid); gBufferManager->UnregisterBuffer(cmd->team, cmd->buffer_id);
break; break;
} }
-4
View File
@@ -6,10 +6,6 @@ UsePrivateHeaders media shared ;
AddResources media_addon_server : media_addon_server.rdef ; AddResources media_addon_server : media_addon_server.rdef ;
# That's ugly. The header (ServerInterface.h) should reside in
# headers/private/media.
SubDirHdrs [ FDirName $(HAIKU_TOP) src servers media ] ;
Server media_addon_server : Server media_addon_server :
main.cpp main.cpp
MediaFilePlayer.cpp MediaFilePlayer.cpp
File diff suppressed because it is too large Load Diff