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:
@@ -9,7 +9,10 @@
|
||||
#include <MediaDefs.h>
|
||||
|
||||
|
||||
struct _shared_buffer_list;
|
||||
namespace BPrivate {
|
||||
class BufferCache;
|
||||
class SharedBufferList;
|
||||
}
|
||||
|
||||
|
||||
struct buffer_clone_info {
|
||||
@@ -54,8 +57,8 @@ public:
|
||||
size_t Size();
|
||||
|
||||
private:
|
||||
friend struct _buffer_id_cache;
|
||||
friend struct _shared_buffer_list;
|
||||
friend class BPrivate::BufferCache;
|
||||
friend class BPrivate::SharedBufferList;
|
||||
friend class BMediaRoster;
|
||||
friend class BBufferProducer;
|
||||
friend class BBufferConsumer;
|
||||
@@ -73,15 +76,14 @@ private:
|
||||
void SetHeader(const media_header* header);
|
||||
|
||||
media_header fMediaHeader;
|
||||
_shared_buffer_list* fBufferList;
|
||||
BPrivate::SharedBufferList* fBufferList;
|
||||
area_id fArea;
|
||||
void* fData;
|
||||
size_t fOffset;
|
||||
size_t fSize;
|
||||
media_buffer_id fBufferID;
|
||||
int32 fFlags;
|
||||
|
||||
uint32 _reserved[11];
|
||||
uint32 _reserved[12];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
class BBuffer;
|
||||
class BBufferGroup;
|
||||
class BRegion;
|
||||
class _buffer_id_cache;
|
||||
|
||||
namespace BPrivate {
|
||||
class BufferCache;
|
||||
namespace media {
|
||||
class BMediaRosterEx;
|
||||
}
|
||||
@@ -147,7 +147,7 @@ private:
|
||||
|
||||
private:
|
||||
media_type fConsumerType;
|
||||
_buffer_id_cache* fBufferCache;
|
||||
BPrivate::BufferCache* fBufferCache;
|
||||
BBufferGroup* fDeleteBufferGroup;
|
||||
uint32 _reserved[14];
|
||||
};
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
|
||||
class BBuffer;
|
||||
struct _shared_buffer_list;
|
||||
namespace BPrivate {
|
||||
struct SharedBufferList;
|
||||
}
|
||||
|
||||
|
||||
class BBufferGroup {
|
||||
@@ -53,12 +55,12 @@ private:
|
||||
status_t _Init();
|
||||
|
||||
private:
|
||||
friend struct _shared_buffer_list;
|
||||
friend struct BPrivate::SharedBufferList;
|
||||
|
||||
status_t fInitError;
|
||||
status_t fRequestError;
|
||||
int32 fBufferCount;
|
||||
_shared_buffer_list* fBufferList;
|
||||
BPrivate::SharedBufferList* fBufferList;
|
||||
sem_id fReclaimSem;
|
||||
|
||||
uint32 _reserved[9];
|
||||
|
||||
@@ -286,8 +286,8 @@ enum {
|
||||
};
|
||||
|
||||
struct addonserver_instantiate_dormant_node_request : request_data {
|
||||
media_addon_id addonid;
|
||||
int32 flavorid;
|
||||
media_addon_id addon_id;
|
||||
int32 flavor_id;
|
||||
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 {
|
||||
media_addon_id addonid;
|
||||
int32 flavorid;
|
||||
media_addon_id addon_id;
|
||||
int32 flavor_id;
|
||||
int32 delta; // must be +1 or -1
|
||||
team_id team;
|
||||
};
|
||||
@@ -624,17 +624,17 @@ struct server_register_node_request : request_data {
|
||||
};
|
||||
|
||||
struct server_register_node_reply : reply_data {
|
||||
media_node_id nodeid;
|
||||
media_node_id node_id;
|
||||
};
|
||||
|
||||
struct server_unregister_node_request : request_data {
|
||||
media_node_id nodeid;
|
||||
media_node_id node_id;
|
||||
team_id team;
|
||||
};
|
||||
|
||||
struct server_unregister_node_reply : reply_data {
|
||||
media_addon_id addonid;
|
||||
int32 flavorid;
|
||||
media_addon_id addon_id;
|
||||
int32 flavor_id;
|
||||
};
|
||||
|
||||
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 {
|
||||
media_node_id nodeid;
|
||||
media_node_id node_id;
|
||||
};
|
||||
|
||||
struct server_get_node_for_request : request_data {
|
||||
media_node_id nodeid;
|
||||
media_node_id node_id;
|
||||
team_id team;
|
||||
};
|
||||
|
||||
@@ -713,7 +713,7 @@ struct server_rescan_defaults_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 {
|
||||
@@ -724,15 +724,15 @@ struct server_register_mediaaddon_request : request_data {
|
||||
};
|
||||
|
||||
struct server_register_mediaaddon_reply : reply_data {
|
||||
media_addon_id addonid;
|
||||
media_addon_id addon_id;
|
||||
};
|
||||
|
||||
struct server_unregister_mediaaddon_command : command_data {
|
||||
media_addon_id addonid;
|
||||
media_addon_id addon_id;
|
||||
};
|
||||
|
||||
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 {
|
||||
@@ -757,7 +757,7 @@ struct server_register_buffer_reply : reply_data {
|
||||
|
||||
struct server_unregister_buffer_command : command_data {
|
||||
team_id team;
|
||||
media_buffer_id bufferid;
|
||||
media_buffer_id buffer_id;
|
||||
};
|
||||
|
||||
struct server_rewindtypes_request : request_data {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef _NOTIFICATIONS_H
|
||||
#define _NOTIFICATIONS_H
|
||||
|
||||
|
||||
#include <MediaNode.h>
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
namespace media {
|
||||
namespace notifications {
|
||||
@@ -15,7 +18,7 @@ namespace notifications {
|
||||
* The notifications marked with "N" are only send when the
|
||||
* media_node specific BMediaRoster::StartWatching() is used
|
||||
* and the notification belongs to the watched node.
|
||||
*
|
||||
*
|
||||
* In addition, anyone watching a specific node will also receive
|
||||
* error notifications generated by BMediaNode::ReportError()
|
||||
*
|
||||
@@ -35,13 +38,13 @@ namespace notifications {
|
||||
* B_MEDIA_NODE_STOPPED N "node", "when"
|
||||
* B_MEDIA_FLAVORS_CHANGED "be:addon_id", "be:new_count", "be:gone_count"
|
||||
*/
|
||||
|
||||
|
||||
// used for BMediaRoster::StartWatching() parameter validation
|
||||
bool IsValidNotificationRequest(bool node_specific, int32 notification);
|
||||
|
||||
// called by BMediaRoster::StartWatching()
|
||||
status_t Register(const BMessenger ¬ifyHandler, const media_node &node, int32 notification);
|
||||
|
||||
|
||||
// called by BMediaRoster::StopWatching()
|
||||
status_t Unregister(const BMessenger ¬ifyHandler, const media_node &node, int32 notification);
|
||||
|
||||
@@ -54,20 +57,20 @@ namespace notifications {
|
||||
void ConnectionBroken(const media_source &source, const media_destination &destination);
|
||||
void BuffersCreated(area_info *areas, int32 count);
|
||||
void BuffersDeleted(const media_buffer_id *ids, int32 count);
|
||||
|
||||
|
||||
// called by BMediaNode::NodeStopped()
|
||||
void NodeStopped(const media_node &node, bigtime_t when);
|
||||
|
||||
// called by BControllable::BroadcastChangedParameter()
|
||||
status_t ParameterChanged(const media_node &node, int32 parameterid);
|
||||
|
||||
|
||||
// called by BControllable::SetParameterWeb()
|
||||
void WebChanged(const media_node &node);
|
||||
|
||||
|
||||
// called by BControllable::BroadcastNewParameterValue()
|
||||
status_t NewParameterValue(const media_node &node, int32 parameterid, bigtime_t when, const void *param, size_t paramsize);
|
||||
|
||||
// called by the media_addon_server AFTER a flavor change has been
|
||||
|
||||
// called by the media_addon_server AFTER a flavor change has been
|
||||
// handled. NOT CALLED by BMediaAddOn::NotifyFlavorChange()
|
||||
void FlavorsChanged(media_addon_id addonid, int32 newcount, int32 gonecount);
|
||||
|
||||
|
||||
@@ -1,30 +1,28 @@
|
||||
/***********************************************************************
|
||||
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved.
|
||||
* This file may be used under the terms of the OpenBeOS License.
|
||||
*
|
||||
* A pool of kernel ports
|
||||
***********************************************************************/
|
||||
/*
|
||||
* Copyright 2002, Marcus Overhagen. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _POOL_PORT_H_
|
||||
#define _POOL_PORT_H_
|
||||
|
||||
class PortPool
|
||||
{
|
||||
|
||||
class PortPool {
|
||||
public:
|
||||
PortPool();
|
||||
~PortPool();
|
||||
|
||||
|
||||
port_id GetPort();
|
||||
void PutPort(port_id port);
|
||||
void PutPort(port_id port);
|
||||
|
||||
private:
|
||||
void Lock();
|
||||
void Unlock();
|
||||
|
||||
struct PortInfo
|
||||
{
|
||||
struct PortInfo {
|
||||
port_id port;
|
||||
bool used;
|
||||
};
|
||||
|
||||
PortInfo * pool;
|
||||
int count;
|
||||
int maxcount;
|
||||
|
||||
@@ -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_
|
||||
@@ -1,53 +1,66 @@
|
||||
/***********************************************************************
|
||||
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved.
|
||||
* This file may be used under the terms of the OpenBeOS License.
|
||||
*
|
||||
* Used for BBufferGroup and BBuffer management across teams
|
||||
***********************************************************************/
|
||||
/*
|
||||
* Copyright 2009, Axel Dörfler, [email protected].
|
||||
* Copyright 2002, Marcus Overhagen. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SHARED_BUFFER_LIST_H_
|
||||
#define _SHARED_BUFFER_LIST_H_
|
||||
|
||||
|
||||
#include <Buffer.h>
|
||||
|
||||
// created in the media server, cloned into
|
||||
// each BBufferGroup (visible in all address spaces / teams)
|
||||
struct _shared_buffer_list
|
||||
{
|
||||
struct _shared_buffer_info
|
||||
{
|
||||
media_buffer_id id;
|
||||
BBuffer * buffer;
|
||||
bool reclaimed;
|
||||
// the reclaim_sem belonging to the BBufferGroup of this BBuffer
|
||||
// also used as a unique identifier of the group
|
||||
sem_id reclaim_sem;
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
|
||||
class SharedBufferList {
|
||||
public:
|
||||
static area_id Create(SharedBufferList** _list);
|
||||
static SharedBufferList* Get(area_id area);
|
||||
|
||||
void Put();
|
||||
void DeleteGroupAndPut(sem_id groupReclaimSem);
|
||||
|
||||
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;
|
||||
int32 locker_atom;
|
||||
|
||||
// always only the first "buffercount" entries in the "info" array are used
|
||||
int32 buffercount;
|
||||
_shared_buffer_info info[MAX_BUFFER];
|
||||
enum { kMaxBuffers = 2047 };
|
||||
// 16 bytes per buffer, 8 pages in total (one entry less for the list)
|
||||
|
||||
status_t AddBuffer(sem_id group_reclaim_sem, BBuffer *buffer);
|
||||
status_t RequestBuffer(sem_id group_reclaim_sem, int32 buffers_in_group, size_t size, media_buffer_id wantID, BBuffer **buffer, bigtime_t timeout);
|
||||
status_t GetBufferList(sem_id group_reclaim_sem, int32 buf_count, BBuffer **out_buffers);
|
||||
status_t RecycleBuffer(BBuffer *buffer);
|
||||
|
||||
|
||||
status_t Init();
|
||||
status_t _Init();
|
||||
void _RequestBufferInOtherGroups(
|
||||
sem_id groupReclaimSem, media_buffer_id id);
|
||||
|
||||
static _shared_buffer_list *Clone(area_id id = -1);
|
||||
void Terminate(sem_id group_reclaim_sem);
|
||||
void Unmap();
|
||||
private:
|
||||
sem_id fSemaphore;
|
||||
vint32 fAtom;
|
||||
|
||||
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);
|
||||
_shared_buffer_info fInfos[kMaxBuffers];
|
||||
int32 fCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
|
||||
#endif // _SHARED_BUFFER_LIST_H_
|
||||
|
||||
+37
-36
@@ -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]>
|
||||
*
|
||||
@@ -24,12 +29,12 @@
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <Buffer.h>
|
||||
|
||||
#include <AppMisc.h>
|
||||
#include <MediaDefs.h>
|
||||
|
||||
#include "debug.h"
|
||||
@@ -37,9 +42,6 @@
|
||||
#include "SharedBufferList.h"
|
||||
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
extern team_id team;
|
||||
} }
|
||||
using namespace BPrivate::media;
|
||||
|
||||
|
||||
@@ -49,11 +51,11 @@ using namespace BPrivate::media;
|
||||
buffer_clone_info::buffer_clone_info()
|
||||
{
|
||||
CALLED();
|
||||
buffer = 0;
|
||||
area = 0;
|
||||
offset = 0;
|
||||
size = 0;
|
||||
flags = 0;
|
||||
buffer = 0;
|
||||
area = 0;
|
||||
offset = 0;
|
||||
size = 0;
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,11 +124,11 @@ BBuffer::CloneInfo() const
|
||||
CALLED();
|
||||
buffer_clone_info info;
|
||||
|
||||
info.buffer = fBufferID;
|
||||
info.area = fArea;
|
||||
info.offset = fOffset;
|
||||
info.size = fSize;
|
||||
info.flags = fFlags;
|
||||
info.buffer = fMediaHeader.buffer;
|
||||
info.area = fArea;
|
||||
info.offset = fOffset;
|
||||
info.size = fSize;
|
||||
info.flags = fFlags;
|
||||
|
||||
return info;
|
||||
}
|
||||
@@ -137,7 +139,6 @@ BBuffer::ID()
|
||||
{
|
||||
CALLED();
|
||||
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)
|
||||
:
|
||||
// must all be NULL/0 if not correct initialized
|
||||
fBufferList(NULL),
|
||||
// must all be NULL/0 if not correctly initialized
|
||||
fBufferList(NULL),
|
||||
fData(NULL),
|
||||
fSize(0),
|
||||
fBufferID(0)
|
||||
// must be 0 if not registered
|
||||
fSize(0)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
fMediaHeader.buffer = 0;
|
||||
// must be 0 if not registered
|
||||
|
||||
// special case for BSmallBuffer
|
||||
if (info.area == 0 && info.buffer == 0)
|
||||
return;
|
||||
@@ -208,7 +210,7 @@ BBuffer::BBuffer(const buffer_clone_info& info)
|
||||
return;
|
||||
}
|
||||
|
||||
fBufferList = _shared_buffer_list::Clone(areaReply.area);
|
||||
fBufferList = BPrivate::SharedBufferList::Get(areaReply.area);
|
||||
if (fBufferList == NULL) {
|
||||
ERROR("BBuffer::BBuffer: _shared_buffer_list::Clone() failed\n");
|
||||
return;
|
||||
@@ -217,7 +219,7 @@ BBuffer::BBuffer(const buffer_clone_info& info)
|
||||
server_register_buffer_request request;
|
||||
server_register_buffer_reply reply;
|
||||
|
||||
request.team = team;
|
||||
request.team = BPrivate::current_team();
|
||||
request.info = info;
|
||||
|
||||
// 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
|
||||
// to clone the memory for this buffer
|
||||
fBufferID = reply.info.buffer;
|
||||
fSize = reply.info.size;
|
||||
fFlags = reply.info.flags;
|
||||
fOffset = reply.info.offset;
|
||||
fMediaHeader.size_used = 0;
|
||||
fMediaHeader.buffer = reply.info.buffer;
|
||||
|
||||
fArea = clone_area("a cloned BBuffer", &fData, B_ANY_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA, reply.info.area);
|
||||
@@ -256,28 +259,26 @@ BBuffer::BBuffer(const buffer_clone_info& info)
|
||||
}
|
||||
|
||||
fData = (char*)fData + fOffset;
|
||||
fMediaHeader.size_used = 0;
|
||||
fMediaHeader.buffer = fBufferID;
|
||||
}
|
||||
|
||||
|
||||
BBuffer::~BBuffer()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
// unmap the BufferList
|
||||
if (fBufferList != NULL)
|
||||
fBufferList->Unmap();
|
||||
fBufferList->Put();
|
||||
|
||||
// unmap the Data
|
||||
if (fData != NULL) {
|
||||
delete_area(fArea);
|
||||
|
||||
// ask media_server to unregister the buffer
|
||||
// when the last clone of this buffer is gone,
|
||||
// media_server will also remove it's cached area
|
||||
// Ask media_server to unregister the buffer when the last clone of
|
||||
// this buffer is gone, media_server will also remove its cached area.
|
||||
server_unregister_buffer_command cmd;
|
||||
cmd.team = team;
|
||||
cmd.bufferid = fBufferID;
|
||||
cmd.team = BPrivate::current_team();
|
||||
cmd.buffer_id = fMediaHeader.buffer;
|
||||
SendToServer(SERVER_UNREGISTER_BUFFER, &cmd, sizeof(cmd));
|
||||
}
|
||||
}
|
||||
@@ -287,14 +288,14 @@ void
|
||||
BBuffer::SetHeader(const media_header* header)
|
||||
{
|
||||
CALLED();
|
||||
ASSERT(header->buffer == fMediaHeader.buffer);
|
||||
if (header->buffer != fMediaHeader.buffer)
|
||||
debugger("oops");
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
+170
-172
@@ -24,37 +24,35 @@
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "BufferCache.h"
|
||||
#include <BufferConsumer.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <BufferProducer.h>
|
||||
#include <BufferGroup.h>
|
||||
#include <Buffer.h>
|
||||
#include <TimeSource.h> //for debugging
|
||||
#include <stdlib.h>
|
||||
#include "debug.h"
|
||||
#include "MediaMisc.h"
|
||||
#include "DataExchange.h"
|
||||
#include "BufferIdCache.h"
|
||||
#include <TimeSource.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <MediaMisc.h>
|
||||
#include <DataExchange.h>
|
||||
|
||||
|
||||
/*************************************************************
|
||||
* protected BBufferConsumer
|
||||
*************************************************************/
|
||||
|
||||
/* virtual */
|
||||
BBufferConsumer::~BBufferConsumer()
|
||||
{
|
||||
CALLED();
|
||||
delete fBufferCache;
|
||||
if (fDeleteBufferGroup)
|
||||
delete fDeleteBufferGroup;
|
||||
delete fDeleteBufferGroup;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************
|
||||
* public BBufferConsumer
|
||||
*************************************************************/
|
||||
// #pragma mark - public BBufferConsumer
|
||||
|
||||
|
||||
media_type
|
||||
BBufferConsumer::ConsumerType()
|
||||
@@ -64,97 +62,97 @@ BBufferConsumer::ConsumerType()
|
||||
}
|
||||
|
||||
|
||||
/* static */ status_t
|
||||
BBufferConsumer::RegionToClipData(const BRegion *region,
|
||||
int32 *format,
|
||||
int32 *ioSize,
|
||||
void *data)
|
||||
/*static*/ status_t
|
||||
BBufferConsumer::RegionToClipData(const BRegion* region, int32* _format,
|
||||
int32 *_size, void* data)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
status_t rv;
|
||||
int count;
|
||||
|
||||
count = *ioSize / sizeof(int16);
|
||||
rv = BBufferProducer::clip_region_to_shorts(region, static_cast<int16 *>(data), count, &count);
|
||||
*ioSize = count * sizeof(int16);
|
||||
*format = BBufferProducer::B_CLIP_SHORT_RUNS;
|
||||
|
||||
return rv;
|
||||
int count = *_size / sizeof(int16);
|
||||
status_t status = BBufferProducer::clip_region_to_shorts(region,
|
||||
static_cast<int16 *>(data), count, &count);
|
||||
|
||||
*_size = count * sizeof(int16);
|
||||
*_format = BBufferProducer::B_CLIP_SHORT_RUNS;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* protected BBufferConsumer
|
||||
*************************************************************/
|
||||
|
||||
/* explicit */
|
||||
BBufferConsumer::BBufferConsumer(media_type consumer_type) :
|
||||
// #pragma mark - protected BBufferConsumer
|
||||
|
||||
|
||||
BBufferConsumer::BBufferConsumer(media_type consumerType)
|
||||
:
|
||||
BMediaNode("called by BBufferConsumer"),
|
||||
fConsumerType(consumer_type),
|
||||
fBufferCache(new _buffer_id_cache),
|
||||
fConsumerType(consumerType),
|
||||
fBufferCache(new BPrivate::BufferCache),
|
||||
fDeleteBufferGroup(0)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
|
||||
AddNodeKind(B_BUFFER_CONSUMER);
|
||||
}
|
||||
|
||||
|
||||
/* static */ void
|
||||
BBufferConsumer::NotifyLateProducer(const media_source &what_source,
|
||||
bigtime_t how_much,
|
||||
bigtime_t performance_time)
|
||||
/*static*/ void
|
||||
BBufferConsumer::NotifyLateProducer(const media_source& whatSource,
|
||||
bigtime_t howMuch, bigtime_t performanceTime)
|
||||
{
|
||||
CALLED();
|
||||
if (IS_INVALID_SOURCE(what_source))
|
||||
if (IS_INVALID_SOURCE(whatSource))
|
||||
return;
|
||||
|
||||
producer_late_notice_received_command command;
|
||||
command.source = what_source;
|
||||
command.how_much = how_much;
|
||||
command.performance_time = performance_time;
|
||||
|
||||
SendToPort(what_source.port, PRODUCER_LATE_NOTICE_RECEIVED, &command, sizeof(command));
|
||||
command.source = whatSource;
|
||||
command.how_much = howMuch;
|
||||
command.performance_time = performanceTime;
|
||||
|
||||
SendToPort(whatSource.port, PRODUCER_LATE_NOTICE_RECEIVED, &command,
|
||||
sizeof(command));
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BBufferConsumer::SetVideoClippingFor(const media_source &output,
|
||||
const media_destination &destination,
|
||||
const int16 *shorts,
|
||||
int32 short_count,
|
||||
const media_video_display_info &display,
|
||||
void *user_data,
|
||||
int32 *change_tag,
|
||||
void *_reserved_)
|
||||
BBufferConsumer::SetVideoClippingFor(const media_source& output,
|
||||
const media_destination& destination, const int16* shorts, int32 shortCount,
|
||||
const media_video_display_info& display, void* userData, int32* _changeTag,
|
||||
void *_reserved_)
|
||||
{
|
||||
CALLED();
|
||||
if (IS_INVALID_SOURCE(output))
|
||||
return B_MEDIA_BAD_SOURCE;
|
||||
if (IS_INVALID_DESTINATION(destination))
|
||||
return B_MEDIA_BAD_DESTINATION;
|
||||
if (short_count > int(B_MEDIA_MESSAGE_SIZE - sizeof(producer_video_clipping_changed_command)) / 2)
|
||||
debugger("BBufferConsumer::SetVideoClippingFor short_count too large (8000 limit)\n");
|
||||
|
||||
producer_video_clipping_changed_command *command;
|
||||
size_t size;
|
||||
status_t rv;
|
||||
if (shortCount > int(B_MEDIA_MESSAGE_SIZE
|
||||
- sizeof(producer_video_clipping_changed_command)) / 2) {
|
||||
debugger("BBufferConsumer::SetVideoClippingFor short_count too large "
|
||||
"(8000 limit)\n");
|
||||
}
|
||||
|
||||
producer_video_clipping_changed_command* command;
|
||||
size_t size = sizeof(producer_video_clipping_changed_command)
|
||||
+ 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->destination = destination;
|
||||
command->display = display;
|
||||
command->user_data = user_data;
|
||||
command->user_data = userData;
|
||||
command->change_tag = NewChangeTag();
|
||||
command->short_count = short_count;
|
||||
memcpy(command->shorts, shorts, short_count * sizeof(short));
|
||||
if (change_tag != NULL)
|
||||
*change_tag = command->change_tag;
|
||||
|
||||
rv = SendToPort(output.port, PRODUCER_VIDEO_CLIPPING_CHANGED, command, size);
|
||||
command->short_count = shortCount;
|
||||
memcpy(command->shorts, shorts, shortCount * sizeof(short));
|
||||
if (_changeTag != NULL)
|
||||
*_changeTag = command->change_tag;
|
||||
|
||||
status_t status = SendToPort(output.port, PRODUCER_VIDEO_CLIPPING_CHANGED,
|
||||
command, size);
|
||||
|
||||
free(command);
|
||||
return rv;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +171,7 @@ BBufferConsumer::SetOutputEnabled(const media_source &source,
|
||||
return B_MEDIA_BAD_DESTINATION;
|
||||
|
||||
producer_enable_output_command command;
|
||||
|
||||
|
||||
command.source = source;
|
||||
command.destination = destination;
|
||||
command.enabled = enabled;
|
||||
@@ -181,7 +179,7 @@ BBufferConsumer::SetOutputEnabled(const media_source &source,
|
||||
command.change_tag = NewChangeTag();
|
||||
if (change_tag != NULL)
|
||||
*change_tag = command.change_tag;
|
||||
|
||||
|
||||
return SendToPort(source.port, PRODUCER_ENABLE_OUTPUT, &command, sizeof(command));
|
||||
}
|
||||
|
||||
@@ -201,7 +199,7 @@ BBufferConsumer::RequestFormatChange(const media_source &source,
|
||||
return B_MEDIA_BAD_DESTINATION;
|
||||
|
||||
producer_format_change_requested_command command;
|
||||
|
||||
|
||||
command.source = source;
|
||||
command.destination = destination;
|
||||
command.format = to_format;
|
||||
@@ -209,7 +207,7 @@ BBufferConsumer::RequestFormatChange(const media_source &source,
|
||||
command.change_tag = NewChangeTag();
|
||||
if (change_tag != NULL)
|
||||
*change_tag = command.change_tag;
|
||||
|
||||
|
||||
return SendToPort(source.port, PRODUCER_FORMAT_CHANGE_REQUESTED, &command, sizeof(command));
|
||||
}
|
||||
|
||||
@@ -224,46 +222,41 @@ BBufferConsumer::RequestAdditionalBuffer(const media_source &source,
|
||||
return B_MEDIA_BAD_SOURCE;
|
||||
|
||||
producer_additional_buffer_requested_command command;
|
||||
|
||||
|
||||
command.source = source;
|
||||
command.prev_buffer = prev_buffer->ID();
|
||||
command.prev_time = 0;
|
||||
command.has_seek_tag = false;
|
||||
//command.prev_tag =
|
||||
|
||||
//command.prev_tag =
|
||||
|
||||
return SendToPort(source.port, PRODUCER_ADDITIONAL_BUFFER_REQUESTED, &command, sizeof(command));
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BBufferConsumer::RequestAdditionalBuffer(const media_source &source,
|
||||
bigtime_t start_time,
|
||||
void *_reserved)
|
||||
BBufferConsumer::RequestAdditionalBuffer(const media_source& source,
|
||||
bigtime_t startTime, void *_reserved)
|
||||
{
|
||||
CALLED();
|
||||
if (IS_INVALID_SOURCE(source))
|
||||
return B_MEDIA_BAD_SOURCE;
|
||||
|
||||
producer_additional_buffer_requested_command command;
|
||||
|
||||
|
||||
command.source = source;
|
||||
command.prev_buffer = 0;
|
||||
command.prev_time = start_time;
|
||||
command.prev_time = startTime;
|
||||
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
|
||||
BBufferConsumer::SetOutputBuffersFor(const media_source &source,
|
||||
const media_destination &destination,
|
||||
BBufferGroup *group,
|
||||
void *user_data,
|
||||
int32 *change_tag,
|
||||
bool will_reclaim,
|
||||
void *_reserved_)
|
||||
const media_destination &destination, BBufferGroup *group, void *user_data,
|
||||
int32 *change_tag, bool will_reclaim, void *_reserved_)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
@@ -271,10 +264,10 @@ BBufferConsumer::SetOutputBuffersFor(const media_source &source,
|
||||
return B_MEDIA_BAD_SOURCE;
|
||||
if (IS_INVALID_DESTINATION(destination))
|
||||
return B_MEDIA_BAD_DESTINATION;
|
||||
|
||||
|
||||
producer_set_buffer_group_command *command;
|
||||
BBuffer **buffers;
|
||||
int32 buffer_count;
|
||||
int32 buffer_count;
|
||||
size_t size;
|
||||
status_t rv;
|
||||
|
||||
@@ -284,8 +277,8 @@ BBufferConsumer::SetOutputBuffersFor(const media_source &source,
|
||||
if (B_OK != group->CountBuffers(&buffer_count))
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (buffer_count != 0) {
|
||||
|
||||
if (buffer_count != 0) {
|
||||
buffers = new BBuffer * [buffer_count];
|
||||
if (B_OK != group->GetBufferList(buffer_count, buffers)) {
|
||||
delete [] buffers;
|
||||
@@ -309,11 +302,11 @@ BBufferConsumer::SetOutputBuffersFor(const media_source &source,
|
||||
|
||||
if (change_tag != NULL)
|
||||
*change_tag = command->change_tag;
|
||||
|
||||
|
||||
rv = SendToPort(source.port, PRODUCER_SET_BUFFER_GROUP, command, size);
|
||||
free(command);
|
||||
|
||||
if (rv == B_OK) {
|
||||
if (rv == B_OK) {
|
||||
if (fDeleteBufferGroup) // XXX will leak memory if port write failed
|
||||
delete fDeleteBufferGroup;
|
||||
fDeleteBufferGroup = will_reclaim ? NULL : group;
|
||||
@@ -323,10 +316,8 @@ BBufferConsumer::SetOutputBuffersFor(const media_source &source,
|
||||
|
||||
|
||||
status_t
|
||||
BBufferConsumer::SendLatencyChange(const media_source &source,
|
||||
const media_destination &destination,
|
||||
bigtime_t my_new_latency,
|
||||
uint32 flags)
|
||||
BBufferConsumer::SendLatencyChange(const media_source& source,
|
||||
const media_destination& destination, bigtime_t newLatency, uint32 flags)
|
||||
{
|
||||
CALLED();
|
||||
if (IS_INVALID_SOURCE(source))
|
||||
@@ -335,37 +326,36 @@ BBufferConsumer::SendLatencyChange(const media_source &source,
|
||||
return B_MEDIA_BAD_DESTINATION;
|
||||
|
||||
producer_latency_changed_command command;
|
||||
|
||||
|
||||
command.source = source;
|
||||
command.destination = destination;
|
||||
command.latency = my_new_latency;
|
||||
command.latency = newLatency;
|
||||
command.flags = flags;
|
||||
|
||||
TRACE("###### BBufferConsumer::SendLatencyChange: latency from %ld/%ld to %ld/%ld changed to %Ld\n",
|
||||
source.port, source.id, destination.port, destination.id, my_new_latency);
|
||||
|
||||
return SendToPort(source.port, PRODUCER_LATENCY_CHANGED, &command, sizeof(command));
|
||||
|
||||
TRACE("###### BBufferConsumer::SendLatencyChange: latency from %ld/%ld to "
|
||||
"%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));
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* protected BBufferConsumer
|
||||
*************************************************************/
|
||||
|
||||
/* virtual */ status_t
|
||||
BBufferConsumer::HandleMessage(int32 message,
|
||||
const void *data,
|
||||
size_t size)
|
||||
status_t
|
||||
BBufferConsumer::HandleMessage(int32 message, const void* data, size_t size)
|
||||
{
|
||||
PRINT(4, "BBufferConsumer::HandleMessage %#lx, node %ld\n", message, ID());
|
||||
status_t rv;
|
||||
switch (message) {
|
||||
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;
|
||||
reply.format = request->format;
|
||||
rv = AcceptFormat(request->dest, &reply.format);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
status_t status = AcceptFormat(request->dest, &reply.format);
|
||||
request->SendReply(status, &reply, sizeof(reply));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -390,12 +380,17 @@ BBufferConsumer::HandleMessage(int32 message,
|
||||
|
||||
case CONSUMER_BUFFER_RECEIVED:
|
||||
{
|
||||
const consumer_buffer_received_command *command = static_cast<const consumer_buffer_received_command *>(data);
|
||||
BBuffer *buffer;
|
||||
buffer = fBufferCache->GetBuffer(command->buffer);
|
||||
const consumer_buffer_received_command* command
|
||||
= static_cast<const consumer_buffer_received_command*>(data);
|
||||
|
||||
BBuffer* buffer = fBufferCache->GetBuffer(command->buffer);
|
||||
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);
|
||||
return B_OK;
|
||||
}
|
||||
@@ -425,7 +420,7 @@ BBufferConsumer::HandleMessage(int32 message,
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
case CONSUMER_DISCONNECTED:
|
||||
{
|
||||
const consumer_disconnected_request *request = static_cast<const consumer_disconnected_request *>(data);
|
||||
@@ -464,8 +459,7 @@ BBufferConsumer::HandleMessage(int32 message,
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -482,9 +476,9 @@ BBufferConsumer::SeekTagRequested(const media_destination &destination,
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* private BBufferConsumer
|
||||
*************************************************************/
|
||||
|
||||
// #pragma mark - private BBufferConsumer
|
||||
|
||||
|
||||
/*
|
||||
not implemented:
|
||||
@@ -493,7 +487,9 @@ BBufferConsumer::BBufferConsumer(const BBufferConsumer &clone)
|
||||
BBufferConsumer & BBufferConsumer::operator=(const BBufferConsumer &clone)
|
||||
*/
|
||||
|
||||
/* deprecated function for R4 */
|
||||
|
||||
/*! Deprecated function for BeOS R4.
|
||||
*/
|
||||
/* static */ status_t
|
||||
BBufferConsumer::SetVideoClippingFor(const media_source &output,
|
||||
const int16 *shorts,
|
||||
@@ -506,7 +502,7 @@ BBufferConsumer::SetVideoClippingFor(const media_source &output,
|
||||
return B_MEDIA_BAD_SOURCE;
|
||||
if (short_count > int(B_MEDIA_MESSAGE_SIZE - sizeof(producer_video_clipping_changed_command)) / 2)
|
||||
debugger("BBufferConsumer::SetVideoClippingFor short_count too large (8000 limit)\n");
|
||||
|
||||
|
||||
producer_video_clipping_changed_command *command;
|
||||
size_t size;
|
||||
status_t rv;
|
||||
@@ -522,19 +518,19 @@ BBufferConsumer::SetVideoClippingFor(const media_source &output,
|
||||
memcpy(command->shorts, shorts, short_count * sizeof(short));
|
||||
if (change_tag != NULL)
|
||||
*change_tag = command->change_tag;
|
||||
|
||||
|
||||
rv = SendToPort(output.port, PRODUCER_VIDEO_CLIPPING_CHANGED, command, size);
|
||||
free(command);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* deprecated function for R4 */
|
||||
/* static */ status_t
|
||||
BBufferConsumer::RequestFormatChange(const media_source &source,
|
||||
const media_destination &destination,
|
||||
media_format *in_to_format,
|
||||
int32 *change_tag)
|
||||
/*! Deprecated function for BeOS R4.
|
||||
*/
|
||||
/*static*/ status_t
|
||||
BBufferConsumer::RequestFormatChange(const media_source& source,
|
||||
const media_destination& destination, media_format* format,
|
||||
int32* _changeTag)
|
||||
{
|
||||
CALLED();
|
||||
if (IS_INVALID_SOURCE(source))
|
||||
@@ -543,57 +539,59 @@ BBufferConsumer::RequestFormatChange(const media_source &source,
|
||||
return B_MEDIA_BAD_DESTINATION;
|
||||
|
||||
producer_format_change_requested_command command;
|
||||
|
||||
|
||||
command.source = source;
|
||||
command.destination = destination;
|
||||
command.format = *in_to_format;
|
||||
command.format = *format;
|
||||
command.user_data = 0;
|
||||
command.change_tag = NewChangeTag();
|
||||
if (change_tag != NULL)
|
||||
*change_tag = command.change_tag;
|
||||
|
||||
return SendToPort(source.port, PRODUCER_FORMAT_CHANGE_REQUESTED, &command, sizeof(command));
|
||||
if (_changeTag != NULL)
|
||||
*_changeTag = command.change_tag;
|
||||
|
||||
return SendToPort(source.port, PRODUCER_FORMAT_CHANGE_REQUESTED, &command,
|
||||
sizeof(command));
|
||||
}
|
||||
|
||||
|
||||
/* deprecated function for R4 */
|
||||
/* static */ status_t
|
||||
BBufferConsumer::SetOutputEnabled(const media_source &source,
|
||||
bool enabled,
|
||||
int32 *change_tag)
|
||||
/*! Deprecated function for BeOS R4.
|
||||
*/
|
||||
/*static*/ status_t
|
||||
BBufferConsumer::SetOutputEnabled(const media_source& source, bool enabled,
|
||||
int32* _changeTag)
|
||||
{
|
||||
CALLED();
|
||||
if (IS_INVALID_SOURCE(source))
|
||||
return B_MEDIA_BAD_SOURCE;
|
||||
|
||||
producer_enable_output_command command;
|
||||
|
||||
|
||||
command.source = source;
|
||||
command.destination = media_destination::null;
|
||||
command.enabled = enabled;
|
||||
command.user_data = 0;
|
||||
command.change_tag = NewChangeTag();
|
||||
if (change_tag != NULL)
|
||||
*change_tag = command.change_tag;
|
||||
|
||||
return SendToPort(source.port, PRODUCER_ENABLE_OUTPUT, &command, sizeof(command));
|
||||
if (_changeTag != NULL)
|
||||
*_changeTag = command.change_tag;
|
||||
|
||||
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_1(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_4(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_7(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_10(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_13(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_0(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_3(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_6(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_9(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_12(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_15(void*) { return B_ERROR; }
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@ BBufferGroup::BBufferGroup(size_t size, int32 count, uint32 placement,
|
||||
CALLED();
|
||||
if (_Init() != B_OK)
|
||||
return;
|
||||
|
||||
|
||||
// This one is easy. We need to create "count" BBuffers,
|
||||
// each one "size" bytes large. They all go into one
|
||||
// each one "size" bytes large. They all go into one
|
||||
// area, with "placement" and "lock" attributes.
|
||||
// The BBuffers created will clone the area, and
|
||||
// then we delete our area. This way BBuffers are
|
||||
@@ -57,7 +57,7 @@ BBufferGroup::BBufferGroup(size_t size, int32 count, uint32 placement,
|
||||
"&& placement != B_ANY_KERNEL_ADDRESS (0x%08lx)\n", placement);
|
||||
placement = B_ANY_ADDRESS;
|
||||
}
|
||||
|
||||
|
||||
// first we roundup for a better placement in memory
|
||||
size_t allocSize = (size + 63) & ~63;
|
||||
|
||||
@@ -76,7 +76,7 @@ BBufferGroup::BBufferGroup(size_t size, int32 count, uint32 placement,
|
||||
|
||||
buffer_clone_info info;
|
||||
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
info.area = bufferArea;
|
||||
info.offset = i * allocSize;
|
||||
info.size = size;
|
||||
@@ -95,7 +95,7 @@ BBufferGroup::BBufferGroup()
|
||||
CALLED();
|
||||
if (_Init() != B_OK)
|
||||
return;
|
||||
|
||||
|
||||
// this one simply creates an empty BBufferGroup
|
||||
}
|
||||
|
||||
@@ -105,16 +105,16 @@ BBufferGroup::BBufferGroup(int32 count, const media_buffer_id* buffers)
|
||||
CALLED();
|
||||
if (_Init() != B_OK)
|
||||
return;
|
||||
|
||||
|
||||
// TODO: we need to make sure that a media_buffer_id is only added
|
||||
// once to each group
|
||||
|
||||
// this one creates "BBuffer"s from "media_buffer_id"s passed
|
||||
// this one creates "BBuffer"s from "media_buffer_id"s passed
|
||||
// by the application.
|
||||
|
||||
buffer_clone_info info;
|
||||
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
info.buffer = buffers[i];
|
||||
|
||||
fInitError = AddBuffer(info);
|
||||
@@ -127,8 +127,8 @@ BBufferGroup::BBufferGroup(int32 count, const media_buffer_id* buffers)
|
||||
BBufferGroup::~BBufferGroup()
|
||||
{
|
||||
CALLED();
|
||||
if (fBufferList)
|
||||
fBufferList->Terminate(fReclaimSem);
|
||||
if (fBufferList != NULL)
|
||||
fBufferList->DeleteGroupAndPut(fReclaimSem);
|
||||
|
||||
delete_sem(fReclaimSem);
|
||||
}
|
||||
@@ -188,7 +188,7 @@ BBufferGroup::RequestBuffer(size_t size, bigtime_t timeout)
|
||||
|
||||
if (size <= 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
BBuffer *buffer;
|
||||
status_t status;
|
||||
|
||||
@@ -207,7 +207,7 @@ BBufferGroup::RequestBuffer(BBuffer* buffer, bigtime_t timeout)
|
||||
CALLED();
|
||||
if (fInitError != B_OK)
|
||||
return B_NO_INIT;
|
||||
|
||||
|
||||
if (buffer == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
@@ -215,7 +215,7 @@ BBufferGroup::RequestBuffer(BBuffer* buffer, bigtime_t timeout)
|
||||
status = fBufferList->RequestBuffer(fReclaimSem, fBufferCount, 0, 0,
|
||||
&buffer, timeout);
|
||||
fRequestError = status;
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ BBufferGroup::GetBufferList(int32 bufferCount, BBuffer** _buffers)
|
||||
CALLED();
|
||||
if (fInitError != B_OK)
|
||||
return B_NO_INIT;
|
||||
|
||||
|
||||
if (bufferCount <= 0 || bufferCount > fBufferCount)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
@@ -264,7 +264,7 @@ BBufferGroup::WaitForBuffers()
|
||||
if (fInitError != B_OK)
|
||||
return B_NO_INIT;
|
||||
|
||||
// TODO: this function is not really useful anyway, and will
|
||||
// TODO: this function is not really useful anyway, and will
|
||||
// not work exactly as documented, but it is close enough
|
||||
|
||||
if (fBufferCount < 0)
|
||||
@@ -281,7 +281,7 @@ BBufferGroup::WaitForBuffers()
|
||||
;
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
|
||||
// we need to release the "fReclaimSem" now, else we would block
|
||||
// requesting of new buffers
|
||||
|
||||
@@ -297,7 +297,7 @@ BBufferGroup::ReclaimAllBuffers()
|
||||
return B_NO_INIT;
|
||||
|
||||
// because additional BBuffers might get added to this group betweeen
|
||||
// acquire and release
|
||||
// acquire and release
|
||||
int32 count = fBufferCount;
|
||||
|
||||
if (count < 0)
|
||||
@@ -313,10 +313,10 @@ BBufferGroup::ReclaimAllBuffers()
|
||||
do {
|
||||
status = acquire_sem_etc(fReclaimSem, count, 0, 0);
|
||||
} while (status == B_INTERRUPTED);
|
||||
|
||||
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
|
||||
// we need to release the "fReclaimSem" now, else we would block
|
||||
// requesting of new buffers
|
||||
|
||||
@@ -333,7 +333,7 @@ BBufferGroup::AddBuffersTo(BMessage* message, const char* name, bool needLock)
|
||||
CALLED();
|
||||
if (fInitError != B_OK)
|
||||
return B_NO_INIT;
|
||||
|
||||
|
||||
// BeOS R4 legacy API. Implemented as a wrapper around GetBufferList
|
||||
// "needLock" is ignored, GetBufferList will do locking
|
||||
|
||||
@@ -342,17 +342,17 @@ BBufferGroup::AddBuffersTo(BMessage* message, const char* name, bool needLock)
|
||||
|
||||
if (name == NULL || strlen(name) == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
|
||||
BBuffer** buffers;
|
||||
int32 count;
|
||||
|
||||
|
||||
count = fBufferCount;
|
||||
buffers = new BBuffer * [count];
|
||||
|
||||
status_t status = GetBufferList(count, buffers);
|
||||
if (status != B_OK)
|
||||
goto end;
|
||||
|
||||
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
status = message->AddInt32(name, int32(buffers[i]->ID()));
|
||||
if (status != B_OK)
|
||||
@@ -377,7 +377,7 @@ status_t
|
||||
BBufferGroup::_Init()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
|
||||
// some defaults in case we drop out early
|
||||
fBufferList = 0;
|
||||
fInitError = B_ERROR;
|
||||
@@ -404,9 +404,9 @@ BBufferGroup::_Init()
|
||||
return fInitError;
|
||||
}
|
||||
|
||||
fBufferList = _shared_buffer_list::Clone(areaReply.area);
|
||||
fBufferList = BPrivate::SharedBufferList::Get(areaReply.area);
|
||||
if (fBufferList == NULL) {
|
||||
ERROR("BBufferGroup::InitBufferGroup: _shared_buffer_list::Clone "
|
||||
ERROR("BBufferGroup::InitBufferGroup: SharedBufferList::Get() "
|
||||
"failed\n");
|
||||
fInitError = B_ERROR;
|
||||
return fInitError;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,52 +1,54 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2002-2007, Marcus Overhagen. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <OS.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
#include <DataExchange.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <Messenger.h>
|
||||
#include <OS.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "PortPool.h"
|
||||
#include "MediaMisc.h"
|
||||
#include "DataExchange.h"
|
||||
#include "ServerInterface.h"
|
||||
|
||||
|
||||
#define TIMEOUT 15000000 // 15 seconds timeout!
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
namespace media {
|
||||
|
||||
team_id team;
|
||||
|
||||
namespace dataexchange {
|
||||
|
||||
BMessenger *MediaServerMessenger;
|
||||
|
||||
BMessenger* MediaServerMessenger;
|
||||
static port_id MediaServerPort;
|
||||
static port_id MediaAddonServerPort;
|
||||
|
||||
void find_media_server_port();
|
||||
void find_media_addon_server_port();
|
||||
|
||||
static BMessenger * GetMediaServerMessenger() {
|
||||
static BMessenger * messenger = new BMessenger(B_MEDIA_SERVER_SIGNATURE);
|
||||
static BMessenger*
|
||||
GetMediaServerMessenger()
|
||||
{
|
||||
static BMessenger* messenger = new BMessenger(B_MEDIA_SERVER_SIGNATURE);
|
||||
return MediaServerMessenger = messenger;
|
||||
}
|
||||
|
||||
class initit
|
||||
{
|
||||
class initit {
|
||||
public:
|
||||
initit()
|
||||
{
|
||||
MediaServerMessenger = 0;
|
||||
find_media_server_port();
|
||||
find_media_addon_server_port();
|
||||
|
||||
thread_info info;
|
||||
get_thread_info(find_thread(NULL), &info);
|
||||
team = info.team;
|
||||
}
|
||||
|
||||
~initit()
|
||||
{
|
||||
delete MediaServerMessenger;
|
||||
@@ -55,7 +57,8 @@ public:
|
||||
initit _initit;
|
||||
|
||||
|
||||
void find_media_server_port()
|
||||
void
|
||||
find_media_server_port()
|
||||
{
|
||||
MediaServerPort = find_port(MEDIA_SERVER_PORT_NAME);
|
||||
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);
|
||||
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
|
||||
status_t SendToServer(BMessage *msg)
|
||||
status_t
|
||||
SendToServer(BMessage *msg)
|
||||
{
|
||||
status_t rv;
|
||||
rv = GetMediaServerMessenger()->SendMessage(msg, static_cast<BHandler *>(NULL), TIMEOUT);
|
||||
@@ -96,7 +102,7 @@ status_t SendToServer(BMessage *msg)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
status_t
|
||||
QueryServer(BMessage &request, BMessage &reply)
|
||||
{
|
||||
status_t status = GetMediaServerMessenger()->SendMessage(&request, &reply, TIMEOUT, TIMEOUT);
|
||||
@@ -110,32 +116,37 @@ QueryServer(BMessage &request, BMessage &reply)
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -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;
|
||||
int32 code;
|
||||
@@ -170,7 +182,7 @@ status_t QueryPort(port_id requestport, int32 msgcode, request_data *request, in
|
||||
request->reply_port = _PortPool->GetPort();
|
||||
|
||||
rv = write_port_etc(requestport, msgcode, request, requestsize, B_RELATIVE_TIMEOUT, TIMEOUT);
|
||||
|
||||
|
||||
if (rv != B_OK) {
|
||||
ERROR("QueryPort: write_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, requestport, rv, strerror(rv));
|
||||
if (rv == B_BAD_PORT_ID && requestport == MediaServerPort) {
|
||||
@@ -198,11 +210,10 @@ status_t QueryPort(port_id requestport, int32 msgcode, request_data *request, in
|
||||
if (rv < B_OK) {
|
||||
ERROR("QueryPort: read_port failed, msgcode 0x%lx, port %ld, error %#lx (%s)\n", msgcode, request->reply_port, rv, strerror(rv));
|
||||
}
|
||||
|
||||
|
||||
return (rv < B_OK) ? rv : reply->result;
|
||||
}
|
||||
|
||||
}; // dataexchange
|
||||
}; // media
|
||||
}; // BPrivate
|
||||
|
||||
} // dataexchange
|
||||
} // media
|
||||
} // BPrivate
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
*
|
||||
* Dormant media nodes can be instantiated on demand. The reside on harddisk in the
|
||||
* directories /boot/beos/system/add-ons/media and /boot/home/config/add-ons/media
|
||||
* Multiple media nodes can be included in one file, they can be accessed using the
|
||||
* Multiple media nodes can be included in one file, they can be accessed using the
|
||||
* BMediaAddOn that each file implements.
|
||||
* The BMediaAddOn allows getting a list of supported flavors. Each flavor represents
|
||||
* a media node.
|
||||
* a media node.
|
||||
* The media_addon_server does the initial scanning of files and getting the list
|
||||
* of supported flavors. It uses the flavor_info to do this, and reports the list
|
||||
* of flavors to the media_server packed into individual dormant_media_node
|
||||
@@ -80,7 +80,7 @@ DormantNodeManager::~DormantNodeManager()
|
||||
ERROR("Forcing unload of add-on id %ld with usecount %ld\n", info->addon->AddonID(), info->usecount);
|
||||
UnloadAddon(info->addon, info->image);
|
||||
}
|
||||
|
||||
|
||||
delete fAddonmap;
|
||||
}
|
||||
|
||||
@@ -108,14 +108,14 @@ BMediaAddOn *
|
||||
DormantNodeManager::GetAddon(media_addon_id id)
|
||||
{
|
||||
BMediaAddOn *addon;
|
||||
|
||||
|
||||
TRACE("DormantNodeManager::GetAddon, id %ld\n",id);
|
||||
|
||||
|
||||
// first try to use a already loaded add-on
|
||||
addon = TryGetAddon(id);
|
||||
if (addon)
|
||||
return addon;
|
||||
|
||||
|
||||
// Be careful, we avoid locking here!
|
||||
|
||||
// ok, it's not loaded, try to get the path
|
||||
@@ -124,7 +124,7 @@ DormantNodeManager::GetAddon(media_addon_id id)
|
||||
ERROR("DormantNodeManager::GetAddon: can't find path for add-on %ld\n",id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// try to load it
|
||||
BMediaAddOn *newaddon;
|
||||
image_id image;
|
||||
@@ -132,7 +132,7 @@ DormantNodeManager::GetAddon(media_addon_id id)
|
||||
ERROR("DormantNodeManager::GetAddon: can't load add-on %ld from path %s\n",id, path.Path());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// ok, we successfully loaded it. Now lock and insert it into the map,
|
||||
// or unload it if the map already contains one that was loaded by another
|
||||
// thread at the same time
|
||||
@@ -162,7 +162,7 @@ DormantNodeManager::PutAddonDelayed(media_addon_id id)
|
||||
// We must make sure that the media-add-on stays in memory
|
||||
// a couple of seconds longer.
|
||||
|
||||
UNIMPLEMENTED();
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -174,7 +174,7 @@ DormantNodeManager::PutAddon(media_addon_id id)
|
||||
bool unload;
|
||||
|
||||
TRACE("DormantNodeManager::PutAddon, id %ld\n",id);
|
||||
|
||||
|
||||
fLock->Lock();
|
||||
if (!fAddonmap->Get(id, &info)) {
|
||||
ERROR("DormantNodeManager::PutAddon: failed to find add-on %ld\n",id);
|
||||
@@ -204,9 +204,9 @@ DormantNodeManager::RegisterAddon(const char *path)
|
||||
status_t rv;
|
||||
int32 code;
|
||||
entry_ref tempref;
|
||||
|
||||
|
||||
TRACE("DormantNodeManager::RegisterAddon, path %s\n",path);
|
||||
|
||||
|
||||
rv = get_ref_for_path(path, &tempref);
|
||||
if (rv != B_OK) {
|
||||
ERROR("DormantNodeManager::RegisterAddon failed, couldn't get ref for path %s\n",path);
|
||||
@@ -232,9 +232,10 @@ DormantNodeManager::RegisterAddon(const char *path)
|
||||
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
|
||||
@@ -250,7 +251,7 @@ DormantNodeManager::UnregisterAddon(media_addon_id id)
|
||||
port = find_port(MEDIA_SERVER_PORT_NAME);
|
||||
if (port <= B_OK)
|
||||
return;
|
||||
msg.addonid = id;
|
||||
msg.addon_id = id;
|
||||
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);
|
||||
if (port <= B_OK)
|
||||
return B_ERROR;
|
||||
msg.addonid = id;
|
||||
msg.addon_id = id;
|
||||
msg.reply_port = _PortPool->GetPort();
|
||||
rv = write_port(port, SERVER_GET_MEDIAADDON_REF, &msg, sizeof(msg));
|
||||
if (rv != B_OK) {
|
||||
@@ -291,33 +292,33 @@ DormantNodeManager::LoadAddon(BMediaAddOn **newaddon, image_id *newimage, const
|
||||
BMediaAddOn *addon;
|
||||
image_id image;
|
||||
status_t rv;
|
||||
|
||||
|
||||
image = load_add_on(path);
|
||||
if (image < B_OK) {
|
||||
ERROR("DormantNodeManager::LoadAddon: loading failed, error %lx (%s), path %s\n", image, strerror(image), path);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
rv = get_image_symbol(image, "make_media_addon", B_SYMBOL_TYPE_TEXT, (void**)&make_addon);
|
||||
if (rv < B_OK) {
|
||||
ERROR("DormantNodeManager::LoadAddon: loading failed, function not found, error %lx (%s)\n", rv, strerror(rv));
|
||||
unload_add_on(image);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
addon = make_addon(image);
|
||||
if (addon == 0) {
|
||||
ERROR("DormantNodeManager::LoadAddon: creating BMediaAddOn failed\n");
|
||||
unload_add_on(image);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
ASSERT(addon->ImageID() == image); // this should be true for a well behaving add-on
|
||||
|
||||
// everything ok
|
||||
*newaddon = addon;
|
||||
*newimage = image;
|
||||
|
||||
|
||||
// we are a friend class of BMediaAddOn and initialize these member variables
|
||||
addon->fAddon = id;
|
||||
addon->fImage = image;
|
||||
|
||||
@@ -7,17 +7,12 @@ if $(TARGET_PLATFORM) != haiku {
|
||||
# We need the public media headers also when not compiling for Haiku.
|
||||
}
|
||||
|
||||
UsePrivateHeaders media shared ;
|
||||
UsePrivateHeaders app media shared ;
|
||||
|
||||
if $(CHECK_MALLOC) {
|
||||
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 :
|
||||
# Private Media Kit
|
||||
!missing_symbols.cpp
|
||||
@@ -52,7 +47,7 @@ SharedLibrary libmedia.so :
|
||||
TimeSource.cpp
|
||||
|
||||
# Internal Functionality
|
||||
BufferIdCache.cpp
|
||||
BufferCache.cpp
|
||||
DataExchange.cpp
|
||||
DefaultMediaTheme.cpp
|
||||
DormantNodeManager.cpp
|
||||
|
||||
@@ -104,7 +104,7 @@ dormant_flavor_info::dormant_flavor_info()
|
||||
}
|
||||
|
||||
|
||||
/* virtual */
|
||||
/* virtual */
|
||||
dormant_flavor_info::~dormant_flavor_info()
|
||||
{
|
||||
delete [] name;
|
||||
@@ -182,7 +182,7 @@ dormant_flavor_info::operator=(const flavor_info &clone)
|
||||
// initialize node_info with default values from dormant_node_info constructor
|
||||
dormant_node_info defaultValues;
|
||||
node_info = defaultValues;
|
||||
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ dormant_flavor_info::Flatten(void *buffer,
|
||||
if (size < FlattenedSize())
|
||||
return B_ERROR;
|
||||
|
||||
char *buf = (char *)buffer;
|
||||
char *buf = (char *)buffer;
|
||||
int32 nameLength = name ? (int32)strlen(name) : -1;
|
||||
int32 infoLength = info ? (int32)strlen(info) : -1;
|
||||
int32 inFormatCount = 0;
|
||||
@@ -362,7 +362,7 @@ dormant_flavor_info::Unflatten(type_code c,
|
||||
if (size < 8)
|
||||
return B_ERROR;
|
||||
|
||||
const char *buf = (const char *)buffer;
|
||||
const char *buf = (const char *)buffer;
|
||||
int32 nameLength;
|
||||
int32 infoLength;
|
||||
|
||||
@@ -409,7 +409,7 @@ dormant_flavor_info::Unflatten(type_code c,
|
||||
}
|
||||
|
||||
int32 count;
|
||||
|
||||
|
||||
kinds = *(uint64*)buf; buf += sizeof(uint64);
|
||||
flavor_flags = *(uint32*)buf; buf += sizeof(uint32);
|
||||
internal_id = *(int32*)buf; buf += sizeof(int32);
|
||||
@@ -423,12 +423,12 @@ dormant_flavor_info::Unflatten(type_code c,
|
||||
if (!in_formats)
|
||||
return B_NO_MEMORY;
|
||||
// XXX FIXME! we should not!!! make flat copies of media_format
|
||||
memcpy(const_cast<media_format *>(in_formats), buf, count * sizeof(media_format));
|
||||
memcpy(const_cast<media_format *>(in_formats), buf, count * sizeof(media_format));
|
||||
in_format_count = count;
|
||||
}
|
||||
buf += count * sizeof(media_format); // XXX not save
|
||||
}
|
||||
|
||||
|
||||
count = *(int32*)buf; buf += sizeof(int32);
|
||||
out_format_flags = *(uint32*)buf; buf += sizeof(uint32);
|
||||
|
||||
@@ -438,14 +438,14 @@ dormant_flavor_info::Unflatten(type_code c,
|
||||
if (!out_formats)
|
||||
return B_NO_MEMORY;
|
||||
// XXX FIXME! we should not!!! make flat copies of media_format
|
||||
memcpy(const_cast<media_format *>(out_formats), buf, count * sizeof(media_format));
|
||||
memcpy(const_cast<media_format *>(out_formats), buf, count * sizeof(media_format));
|
||||
out_format_count = count;
|
||||
}
|
||||
buf += count * sizeof(media_format); // XXX not save
|
||||
}
|
||||
|
||||
node_info = *(dormant_node_info*)buf; buf += sizeof(dormant_node_info);
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -453,7 +453,7 @@ dormant_flavor_info::Unflatten(type_code c,
|
||||
* public BMediaAddOn
|
||||
*************************************************************/
|
||||
|
||||
/* explicit */
|
||||
/* explicit */
|
||||
BMediaAddOn::BMediaAddOn(image_id image) :
|
||||
fImage(image),
|
||||
fAddon(0)
|
||||
@@ -462,7 +462,7 @@ BMediaAddOn::BMediaAddOn(image_id image) :
|
||||
}
|
||||
|
||||
|
||||
/* virtual */
|
||||
/* virtual */
|
||||
BMediaAddOn::~BMediaAddOn()
|
||||
{
|
||||
CALLED();
|
||||
@@ -617,7 +617,7 @@ BMediaAddOn::NotifyFlavorChange()
|
||||
return B_ERROR;
|
||||
|
||||
addonserver_rescan_mediaaddon_flavors_command command;
|
||||
command.addonid = fAddon;
|
||||
command.addon_id = fAddon;
|
||||
return SendToAddonServer(ADDONSERVER_RESCAN_MEDIAADDON_FLAVORS, &command, sizeof(command));
|
||||
}
|
||||
|
||||
|
||||
+125
-125
@@ -31,7 +31,6 @@
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -39,7 +38,7 @@
|
||||
char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "
|
||||
"Overhagen <[email protected]>";
|
||||
|
||||
//#define DEBUG 7
|
||||
|
||||
#include <MediaRoster.h>
|
||||
|
||||
#include <new>
|
||||
@@ -56,6 +55,8 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "
|
||||
#include <String.h>
|
||||
#include <TimeSource.h>
|
||||
|
||||
#include <AppMisc.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "MediaRosterEx.h"
|
||||
#include "MediaMisc.h"
|
||||
@@ -68,39 +69,43 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
// the BMediaRoster destructor is private,
|
||||
// but _DefaultDeleter is a friend class of
|
||||
// the BMediaRoster an thus can delete it
|
||||
class DefaultDeleter
|
||||
// the BMediaRoster destructor is private,
|
||||
// but _DefaultDeleter is a friend class of
|
||||
// the BMediaRoster an thus can delete it
|
||||
class DefaultDeleter {
|
||||
public:
|
||||
~DefaultDeleter()
|
||||
{
|
||||
public:
|
||||
~DefaultDeleter()
|
||||
{
|
||||
if (BMediaRoster::sDefaultInstance) {
|
||||
BMediaRoster::sDefaultInstance->Lock();
|
||||
BMediaRoster::sDefaultInstance->Quit();
|
||||
}
|
||||
if (BMediaRoster::sDefaultInstance != NULL) {
|
||||
BMediaRoster::sDefaultInstance->Lock();
|
||||
BMediaRoster::sDefaultInstance->Quit();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace media
|
||||
} // namespace BPrivate
|
||||
|
||||
} } // BPrivate::media
|
||||
using namespace BPrivate::media;
|
||||
|
||||
|
||||
// DefaultDeleter will delete the BMediaRoster object in it's destructor.
|
||||
DefaultDeleter _deleter;
|
||||
|
||||
|
||||
BMediaRosterEx::BMediaRosterEx(status_t* _error)
|
||||
: BMediaRoster()
|
||||
:
|
||||
BMediaRoster()
|
||||
{
|
||||
status_t rv;
|
||||
// register this application with the media server
|
||||
server_register_app_request request;
|
||||
server_register_app_reply reply;
|
||||
request.team = team;
|
||||
request.team = BPrivate::current_team();
|
||||
request.messenger = BMessenger(NULL, this);
|
||||
rv = QueryServer(SERVER_REGISTER_APP, &request, sizeof(request), &reply,
|
||||
sizeof(reply));
|
||||
if (rv != B_OK)
|
||||
|
||||
status_t status = QueryServer(SERVER_REGISTER_APP, &request,
|
||||
sizeof(request), &reply, sizeof(reply));
|
||||
if (status != B_OK)
|
||||
*_error = B_MEDIA_SYSTEM_FAILURE;
|
||||
else
|
||||
*_error = B_OK;
|
||||
@@ -110,11 +115,9 @@ BMediaRosterEx::BMediaRosterEx(status_t* _error)
|
||||
status_t
|
||||
BMediaRosterEx::SaveNodeConfiguration(BMediaNode* node)
|
||||
{
|
||||
BMediaAddOn *addon;
|
||||
media_addon_id addonid;
|
||||
int32 flavorid;
|
||||
addon = node->AddOn(&flavorid);
|
||||
if (!addon) {
|
||||
int32 flavorID;
|
||||
BMediaAddOn* addon = node->AddOn(&flavorID);
|
||||
if (addon == NULL) {
|
||||
// NOTE: This node could have been created by an application,
|
||||
// it does not mean there is an error.
|
||||
// TODO: this check incorrectly triggers on BeOS R5 BT848 node
|
||||
@@ -122,54 +125,55 @@ BMediaRosterEx::SaveNodeConfiguration(BMediaNode* node)
|
||||
"from BMediaAddOn!\n", node->ID());
|
||||
return B_ERROR;
|
||||
}
|
||||
addonid = addon->AddonID();
|
||||
|
||||
media_addon_id addonID = addon->AddonID();
|
||||
|
||||
// TODO: fix this
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRosterEx::LoadNodeConfiguration(media_addon_id addonid, int32 flavorid,
|
||||
BMessage *out_msg)
|
||||
BMediaRosterEx::LoadNodeConfiguration(media_addon_id addonID, int32 flavorID,
|
||||
BMessage *_msg)
|
||||
{
|
||||
// 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 "
|
||||
"%ld, flavor-id %ld config NOW!\n", addonid, flavorid);
|
||||
"%ld, flavor-id %ld config NOW!\n", addonID, flavorID);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRosterEx::IncrementAddonFlavorInstancesCount(media_addon_id addonid,
|
||||
int32 flavorid)
|
||||
BMediaRosterEx::IncrementAddonFlavorInstancesCount(media_addon_id addonID,
|
||||
int32 flavorID)
|
||||
{
|
||||
server_change_addon_flavor_instances_count_request request;
|
||||
server_change_addon_flavor_instances_count_reply reply;
|
||||
|
||||
request.addonid = addonid;
|
||||
request.flavorid = flavorid;
|
||||
request.addon_id = addonID;
|
||||
request.flavor_id = flavorID;
|
||||
request.delta = 1;
|
||||
request.team = team;
|
||||
request.team = BPrivate::current_team();
|
||||
return QueryServer(SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT, &request,
|
||||
sizeof(request), &reply, sizeof(reply));
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRosterEx::DecrementAddonFlavorInstancesCount(media_addon_id addonid,
|
||||
int32 flavorid)
|
||||
BMediaRosterEx::DecrementAddonFlavorInstancesCount(media_addon_id addonID,
|
||||
int32 flavorID)
|
||||
{
|
||||
server_change_addon_flavor_instances_count_request request;
|
||||
server_change_addon_flavor_instances_count_reply reply;
|
||||
|
||||
request.addonid = addonid;
|
||||
request.flavorid = flavorid;
|
||||
request.addon_id = addonID;
|
||||
request.flavor_id = flavorID;
|
||||
request.delta = -1;
|
||||
request.team = team;
|
||||
request.team = BPrivate::current_team();
|
||||
return QueryServer(SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT, &request,
|
||||
sizeof(request), &reply, sizeof(reply));
|
||||
}
|
||||
@@ -200,7 +204,7 @@ BMediaRosterEx::GetNode(node_type type, media_node* out_node,
|
||||
status_t rv;
|
||||
|
||||
request.type = type;
|
||||
request.team = team;
|
||||
request.team = BPrivate::current_team();
|
||||
rv = QueryServer(SERVER_GET_NODE, &request, sizeof(request), &reply,
|
||||
sizeof(reply));
|
||||
if (rv != B_OK)
|
||||
@@ -565,7 +569,7 @@ BMediaRoster::GetAudioOutput(media_node* _node, int32* _inputID,
|
||||
_inputName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRoster::GetTimeSource(media_node* _node)
|
||||
{
|
||||
@@ -673,8 +677,8 @@ BMediaRoster::GetNodeFor(media_node_id node, media_node* clone)
|
||||
server_get_node_for_reply reply;
|
||||
status_t rv;
|
||||
|
||||
request.nodeid = node;
|
||||
request.team = team;
|
||||
request.node_id = node;
|
||||
request.team = BPrivate::current_team();
|
||||
|
||||
rv = QueryServer(SERVER_GET_NODE_FOR, &request, sizeof(request), &reply,
|
||||
sizeof(reply));
|
||||
@@ -720,7 +724,7 @@ BMediaRoster::ReleaseNode(const media_node& node)
|
||||
if (node.kind & NODE_KIND_NO_REFCOUNTING) {
|
||||
printf("BMediaRoster::ReleaseNode, trying to release reference "
|
||||
"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;
|
||||
}
|
||||
|
||||
@@ -729,16 +733,16 @@ BMediaRoster::ReleaseNode(const media_node& node)
|
||||
status_t rv;
|
||||
|
||||
request.node = node;
|
||||
request.team = team;
|
||||
request.team = BPrivate::current_team();
|
||||
|
||||
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,
|
||||
sizeof(reply));
|
||||
if (rv != B_OK) {
|
||||
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;
|
||||
}
|
||||
@@ -1159,7 +1163,7 @@ BMediaRoster::StopNode(const media_node& node, bigtime_t atPerformanceTime,
|
||||
return SendToPort(node.port, NODE_STOP, &command, sizeof(command));
|
||||
}
|
||||
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRoster::SeekNode(const media_node& node, bigtime_t toMediaTime,
|
||||
bigtime_t atPerformanceTime)
|
||||
@@ -1213,7 +1217,7 @@ BMediaRoster::StartTimeSource(const media_node& node, bigtime_t atRealTime)
|
||||
return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRoster::StopTimeSource(const media_node& node, bigtime_t atRealTime,
|
||||
bool immediate)
|
||||
@@ -1250,7 +1254,7 @@ BMediaRoster::StopTimeSource(const media_node& node, bigtime_t atRealTime,
|
||||
return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRoster::SeekTimeSource(const media_node& node,
|
||||
bigtime_t toPerformanceTime, bigtime_t atRealTime)
|
||||
@@ -1312,7 +1316,7 @@ BMediaRoster::SetRunModeNode(const media_node& node, BMediaNode::run_mode mode)
|
||||
return write_port(node.port, NODE_SET_RUN_MODE, &msg, sizeof(msg));
|
||||
}
|
||||
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRoster::PrerollNode(const media_node& node)
|
||||
{
|
||||
@@ -1880,8 +1884,8 @@ BMediaRoster::RegisterNode(BMediaNode* node)
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addonid,
|
||||
int32 flavorid)
|
||||
BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addonID,
|
||||
int32 flavorID)
|
||||
{
|
||||
CALLED();
|
||||
if (node == NULL)
|
||||
@@ -1890,27 +1894,24 @@ BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addonid,
|
||||
// some sanity check
|
||||
// I'm not sure if the media kit warrants to call BMediaNode::AddOn() here.
|
||||
// Perhaps we don't need it.
|
||||
{
|
||||
BMediaAddOn *addon;
|
||||
int32 addon_flavor_id;
|
||||
media_addon_id addon_id;
|
||||
addon_flavor_id = 0;
|
||||
addon = node->AddOn(&addon_flavor_id);
|
||||
addon_id = addon ? addon->AddonID() : -1;
|
||||
ASSERT(addonid == addon_id);
|
||||
ASSERT(flavorid == addon_flavor_id);
|
||||
}
|
||||
DEBUG_ONLY(
|
||||
int32 testFlavorID;
|
||||
BMediaAddOn* addon = node->AddOn(&testFlavorID);
|
||||
|
||||
ASSERT(addonID == addon != NULL ? addon->AddonID() : -1);
|
||||
ASSERT(flavorID == testFlavorID);
|
||||
);
|
||||
|
||||
status_t rv;
|
||||
server_register_node_request request;
|
||||
server_register_node_reply reply;
|
||||
|
||||
request.addon_id = addonid;
|
||||
request.addon_flavor_id = flavorid;
|
||||
request.addon_id = addonID;
|
||||
request.addon_flavor_id = flavorID;
|
||||
strcpy(request.name, node->Name());
|
||||
request.kinds = node->Kinds();
|
||||
request.port = node->ControlPort();
|
||||
request.team = team;
|
||||
request.team = BPrivate::current_team();
|
||||
|
||||
TRACE("BMediaRoster::RegisterNode: sending SERVER_REGISTER_NODE: port "
|
||||
"%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");
|
||||
|
||||
// we are a friend class of BMediaNode and initialize this member variable
|
||||
node->fNodeID = reply.nodeid;
|
||||
ASSERT(reply.nodeid == node->Node().node);
|
||||
ASSERT(reply.nodeid == node->ID());
|
||||
node->fNodeID = reply.node_id;
|
||||
ASSERT(reply.node_id == node->Node().node);
|
||||
ASSERT(reply.node_id == node->ID());
|
||||
|
||||
// call the callback
|
||||
node->NodeRegistered();
|
||||
@@ -1964,19 +1965,18 @@ BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addonid,
|
||||
PublishOutputs(node->Node(), &list);
|
||||
}
|
||||
}
|
||||
if (node->Kinds() & B_BUFFER_CONSUMER) {
|
||||
BBufferConsumer *bc;
|
||||
bc = dynamic_cast<BBufferConsumer *>(node);
|
||||
if (bc) {
|
||||
if ((node->Kinds() & B_BUFFER_CONSUMER) != 0) {
|
||||
BBufferConsumer* consumer = dynamic_cast<BBufferConsumer*>(node);
|
||||
if (consumer != NULL) {
|
||||
List<media_input> list;
|
||||
if (B_OK == GetAllInputs(bc, &list))
|
||||
if (GetAllInputs(consumer, &list) == B_OK)
|
||||
PublishInputs(node->Node(), &list);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
@@ -2005,7 +2005,7 @@ BMediaRoster::UnregisterNode(BMediaNode* node)
|
||||
if (node->fKinds & NODE_KIND_NO_REFCOUNTING) {
|
||||
TRACE("BMediaRoster::UnregisterNode, trying to unregister reference "
|
||||
"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;
|
||||
}
|
||||
if (node->ID() == NODE_UNREGISTERED_ID) {
|
||||
@@ -2030,11 +2030,11 @@ BMediaRoster::UnregisterNode(BMediaNode* node)
|
||||
server_unregister_node_reply reply;
|
||||
status_t rv;
|
||||
|
||||
request.nodeid = node->ID();
|
||||
request.team = team;
|
||||
request.node_id = node->ID();
|
||||
request.team = BPrivate::current_team();
|
||||
|
||||
// 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,
|
||||
sizeof(reply));
|
||||
@@ -2044,17 +2044,17 @@ BMediaRoster::UnregisterNode(BMediaNode* node)
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (reply.addonid != -1) {
|
||||
if (reply.addon_id != -1) {
|
||||
// Small problem here, we can't use DormantNodeManager::PutAddon(), as
|
||||
// UnregisterNode() is called by a dormant node itself (by the
|
||||
// destructor).
|
||||
// The add-on that contains the node needs to remain in memory until the
|
||||
// destructor execution is finished.
|
||||
// DormantNodeManager::PutAddonDelayed() will delay unloading.
|
||||
_DormantNodeManager->PutAddonDelayed(reply.addonid);
|
||||
_DormantNodeManager->PutAddonDelayed(reply.addon_id);
|
||||
|
||||
rv = MediaRosterEx(this)->DecrementAddonFlavorInstancesCount(
|
||||
reply.addonid, reply.flavorid);
|
||||
reply.addon_id, reply.flavor_id);
|
||||
if (rv != B_OK) {
|
||||
ERROR("BMediaRoster::UnregisterNode: "
|
||||
"DecrementAddonFlavorInstancesCount() failed\n");
|
||||
@@ -2275,16 +2275,16 @@ BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count,
|
||||
if (port <= B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
msg.maxcount = *_count;
|
||||
msg.max_count = *_count;
|
||||
msg.has_input = hasInput != NULL;
|
||||
if (hasInput != NULL) {
|
||||
// TODO: we should not make a flat copy of media_format
|
||||
msg.inputformat = *hasInput;
|
||||
msg.input_format = *hasInput;
|
||||
}
|
||||
msg.has_output = hasOutput != NULL;
|
||||
if (hasOutput != NULL) {
|
||||
// TODO: we should not make a flat copy of media_format
|
||||
msg.outputformat = *hasOutput;
|
||||
msg.output_format = *hasOutput;
|
||||
}
|
||||
|
||||
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 "
|
||||
"%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;
|
||||
}
|
||||
@@ -2548,9 +2548,9 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info& info,
|
||||
|
||||
addonserver_instantiate_dormant_node_request request;
|
||||
addonserver_instantiate_dormant_node_reply reply;
|
||||
request.addonid = info.addon;
|
||||
request.flavorid = info.flavor_id;
|
||||
request.creator_team = team;
|
||||
request.addon_id = info.addon;
|
||||
request.flavor_id = info.flavor_id;
|
||||
request.creator_team = BPrivate::current_team();
|
||||
// creator team is allowed to also release global nodes
|
||||
rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request,
|
||||
sizeof(request), &reply, sizeof(reply));
|
||||
@@ -2568,7 +2568,7 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info& info,
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRoster::InstantiateDormantNode(const dormant_node_info& info,
|
||||
media_node* _node)
|
||||
@@ -2611,44 +2611,44 @@ BMediaRosterEx::GetDormantFlavorInfo(media_addon_id addonID, int32 flavorID,
|
||||
if (_flavor == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
xfer_server_get_dormant_flavor_info msg;
|
||||
xfer_server_get_dormant_flavor_info_reply *reply;
|
||||
port_id port;
|
||||
status_t rv;
|
||||
int32 code;
|
||||
|
||||
port = find_port(MEDIA_SERVER_PORT_NAME);
|
||||
if (port < B_OK)
|
||||
port_id port = find_port(MEDIA_SERVER_PORT_NAME);
|
||||
if (port < 0)
|
||||
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)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
xfer_server_get_dormant_flavor_info msg;
|
||||
msg.addon = addonID;
|
||||
msg.flavor_id = flavorID;
|
||||
msg.reply_port = _PortPool->GetPort();
|
||||
rv = write_port(port, SERVER_GET_DORMANT_FLAVOR_INFO, &msg, sizeof(msg));
|
||||
if (rv != B_OK) {
|
||||
status_t status = write_port(port, SERVER_GET_DORMANT_FLAVOR_INFO, &msg,
|
||||
sizeof(msg));
|
||||
if (status != B_OK) {
|
||||
free(reply);
|
||||
_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);
|
||||
|
||||
if (rv < B_OK) {
|
||||
if (status < B_OK) {
|
||||
free(reply);
|
||||
return rv;
|
||||
return status;
|
||||
}
|
||||
|
||||
if (reply->result == B_OK)
|
||||
rv = _flavor->Unflatten(reply->dfi_type, &reply->dfi, reply->dfi_size);
|
||||
else
|
||||
rv = reply->result;
|
||||
if (reply->result == B_OK) {
|
||||
status = _flavor->Unflatten(reply->type, &reply->flattened_data,
|
||||
reply->flattened_size);
|
||||
} else
|
||||
status = reply->result;
|
||||
|
||||
free(reply);
|
||||
return rv;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -2855,20 +2855,20 @@ BMediaRoster::SniffRef(const entry_ref& file, uint64 requireNodeKinds,
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BMimeType aMimeType;
|
||||
|
||||
|
||||
dormant_node_info nodes[30];
|
||||
int32 count = 30;
|
||||
int32 highestCapability = -1;
|
||||
float capability;
|
||||
|
||||
|
||||
media_node node;
|
||||
|
||||
|
||||
// Get all dormant nodes using GetDormantNodes
|
||||
if (GetDormantNodes(nodes, &count, NULL, NULL, NULL, requireNodeKinds | B_FILE_INTERFACE, 0) == B_OK) {
|
||||
// Call SniffRefFor on each node that matches requireNodeKinds
|
||||
for (int32 i=0;i<count;i++) {
|
||||
if (InstantiateDormantNode(nodes[i], &node) == B_OK) {
|
||||
|
||||
|
||||
if (SniffRefFor(node, file, &aMimeType, &capability) == B_OK) {
|
||||
// find the first node that has 100% capability
|
||||
TRACE("%s has a %f%% chance of playing file\n",nodes[i].name, capability * 100.0);
|
||||
@@ -2880,22 +2880,22 @@ BMediaRoster::SniffRef(const entry_ref& file, uint64 requireNodeKinds,
|
||||
ReleaseNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (highestCapability != -1) {
|
||||
*_node = nodes[highestCapability];
|
||||
|
||||
|
||||
TRACE("BMediaRoster::SniffRef: found a node %s addon-id %ld, flavor_id %ld\n",
|
||||
nodes[highestCapability].name, nodes[highestCapability].addon, nodes[highestCapability].flavor_id);
|
||||
|
||||
|
||||
if (mimeType != NULL) {
|
||||
//*mimeType = aMimeType; -- need a copy constructor
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -3028,7 +3028,7 @@ BMediaRoster::NodeIDFor(port_id port)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return reply.nodeid;
|
||||
return reply.node_id;
|
||||
}
|
||||
|
||||
|
||||
@@ -3118,7 +3118,7 @@ BMediaRoster::AudioBufferSizeFor(int32 channelCount, uint32 sampleFormat,
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! Use MediaFlags to inquire about specific features of the Media Kit.
|
||||
Returns < 0 for "not present", positive size for output data size.
|
||||
0 means that the capability is present, but no data about it.
|
||||
@@ -3202,7 +3202,7 @@ BMediaRoster::~BMediaRoster()
|
||||
// unregister this application with the media server
|
||||
server_unregister_app_request request;
|
||||
server_unregister_app_reply reply;
|
||||
request.team = team;
|
||||
request.team = BPrivate::current_team();
|
||||
QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply,
|
||||
sizeof(reply));
|
||||
|
||||
|
||||
@@ -24,78 +24,90 @@
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/* This is a interface class for media kit notifications.
|
||||
* It is private to the media kit which uses it to pass
|
||||
* notifications up to 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
|
||||
* XXX the notification messages.
|
||||
*/
|
||||
|
||||
/*! This is a interface class for media kit notifications.
|
||||
It is private to the media kit which uses it to pass notifications up to
|
||||
the media_server which will broadcast them.
|
||||
*/
|
||||
|
||||
// TODO: The BeBook, MediaDefs.h and the BeOS R5 do list
|
||||
// different strings for the message data fields of
|
||||
// the notification messages.
|
||||
|
||||
|
||||
#include "Notifications.h"
|
||||
|
||||
#include <Messenger.h>
|
||||
#include <MediaNode.h>
|
||||
|
||||
#include <AppMisc.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "DataExchange.h"
|
||||
#include "Notifications.h"
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
namespace media {
|
||||
|
||||
extern team_id team;
|
||||
|
||||
namespace notifications {
|
||||
|
||||
|
||||
status_t
|
||||
Register(const BMessenger ¬ifyHandler, const media_node &node, int32 notification)
|
||||
Register(const BMessenger& notifyHandler, const media_node& node,
|
||||
int32 notification)
|
||||
{
|
||||
CALLED();
|
||||
BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS);
|
||||
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.AddData("node", B_RAW_TYPE, &node, sizeof(node));
|
||||
|
||||
return BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Unregister(const BMessenger ¬ifyHandler, const media_node &node, int32 notification)
|
||||
Unregister(const BMessenger& notifyHandler, const media_node& node,
|
||||
int32 notification)
|
||||
{
|
||||
CALLED();
|
||||
BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS);
|
||||
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.AddData("node", B_RAW_TYPE, &node, sizeof(node));
|
||||
|
||||
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
|
||||
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();
|
||||
BMessage msg;
|
||||
if (info)
|
||||
if (info != NULL)
|
||||
msg = *info;
|
||||
|
||||
msg.what = MEDIA_SERVER_SEND_NOTIFICATIONS;
|
||||
msg.AddInt32(NOTIFICATION_PARAM_WHAT, what);
|
||||
msg.AddInt32("be:node_id", node.node);
|
||||
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
|
||||
|
||||
return BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NodesCreated(const media_node_id *ids, int32 count)
|
||||
NodesCreated(const media_node_id* ids, int32 count)
|
||||
{
|
||||
CALLED();
|
||||
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++) {
|
||||
msg.AddInt32("media_node_id", ids[i]);
|
||||
}
|
||||
|
||||
BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NodesDeleted(const media_node_id *ids, int32 count)
|
||||
NodesDeleted(const media_node_id* ids, int32 count)
|
||||
{
|
||||
CALLED();
|
||||
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++) {
|
||||
msg.AddInt32("media_node_id", ids[i]);
|
||||
}
|
||||
|
||||
BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
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("output", B_RAW_TYPE, &output, sizeof(output));
|
||||
msg.AddData("format", B_RAW_TYPE, &format, sizeof(format));
|
||||
|
||||
BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConnectionBroken(const media_source &source, const media_destination &destination)
|
||||
ConnectionBroken(const media_source& source,
|
||||
const media_destination& destination)
|
||||
{
|
||||
CALLED();
|
||||
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
|
||||
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_BROKEN);
|
||||
msg.AddData("source", B_RAW_TYPE, &source, sizeof(source));
|
||||
msg.AddData("destination", B_RAW_TYPE, &destination, sizeof(destination));
|
||||
|
||||
BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BuffersCreated(area_info *areas, int32 count)
|
||||
BuffersCreated(area_info* areas, int32 count)
|
||||
{
|
||||
CALLED();
|
||||
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
|
||||
@@ -154,12 +172,13 @@ BuffersCreated(area_info *areas, int32 count)
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
msg.AddData("clone_info", B_RAW_TYPE, &areas[i], sizeof(area_info));
|
||||
}
|
||||
|
||||
BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BuffersDeleted(const media_buffer_id *ids, int32 count)
|
||||
BuffersDeleted(const media_buffer_id* ids, int32 count)
|
||||
{
|
||||
CALLED();
|
||||
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++) {
|
||||
msg.AddInt32("media_buffer_id", ids[i]);
|
||||
}
|
||||
|
||||
BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
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("destination", B_RAW_TYPE, &destination, sizeof(destination));
|
||||
msg.AddData("format", B_RAW_TYPE, &format, sizeof(format));
|
||||
|
||||
BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ParameterChanged(const media_node &node, int32 parameterid)
|
||||
ParameterChanged(const media_node& node, int32 parameterID)
|
||||
{
|
||||
CALLED();
|
||||
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
|
||||
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_PARAMETER_CHANGED);
|
||||
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
|
||||
msg.AddInt32("parameter", parameterid);
|
||||
msg.AddInt32("parameter", parameterID);
|
||||
|
||||
return BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WebChanged(const media_node &node)
|
||||
WebChanged(const media_node& node)
|
||||
{
|
||||
CALLED();
|
||||
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
|
||||
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_WEB_CHANGED);
|
||||
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
|
||||
|
||||
BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
|
||||
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NEW_PARAMETER_VALUE);
|
||||
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
|
||||
msg.AddInt32("parameter", parameterid);
|
||||
msg.AddInt32("parameter", parameterID);
|
||||
msg.AddInt64("when", when);
|
||||
msg.AddData("value", B_RAW_TYPE, param, paramsize);
|
||||
|
||||
return BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FlavorsChanged(media_addon_id addonid, int32 newcount, int32 gonecount)
|
||||
FlavorsChanged(media_addon_id addOnID, int32 newCount, int32 goneCount)
|
||||
{
|
||||
CALLED();
|
||||
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
|
||||
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FLAVORS_CHANGED);
|
||||
msg.AddInt32("be:addon_id", addonid);
|
||||
msg.AddInt32("be:new_count", newcount);
|
||||
msg.AddInt32("be:gone_count", gonecount);
|
||||
msg.AddInt32("be:addon_id", addOnID);
|
||||
msg.AddInt32("be:new_count", newCount);
|
||||
msg.AddInt32("be:gone_count", goneCount);
|
||||
|
||||
BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NodeStopped(const media_node &node, bigtime_t when)
|
||||
NodeStopped(const media_node& node, bigtime_t when)
|
||||
{
|
||||
CALLED();
|
||||
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
|
||||
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_STOPPED);
|
||||
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
|
||||
msg.AddInt64("when", when);
|
||||
|
||||
BPrivate::media::dataexchange::SendToServer(&msg);
|
||||
}
|
||||
|
||||
|
||||
// XXX missing: B_MEDIA_TRANSPORT_STATE /* "state", "location", "realtime" */
|
||||
// XXX missing: B_MEDIA_DEFAULT_CHANGED /* "default", "node" */
|
||||
// TODO: missing: B_MEDIA_TRANSPORT_STATE: "state", "location", "realtime"
|
||||
// TODO: missing: B_MEDIA_DEFAULT_CHANGED: "default", "node"
|
||||
|
||||
|
||||
bool
|
||||
@@ -266,7 +294,7 @@ IsValidNotificationRequest(bool node_specific, int32 notification)
|
||||
case B_MEDIA_DEFAULT_CHANGED:
|
||||
case B_MEDIA_FLAVORS_CHANGED:
|
||||
return true;
|
||||
|
||||
|
||||
// only valid for node specific watching
|
||||
case B_MEDIA_PARAMETER_CHANGED:
|
||||
case B_MEDIA_FORMAT_CHANGED:
|
||||
@@ -274,13 +302,13 @@ IsValidNotificationRequest(bool node_specific, int32 notification)
|
||||
case B_MEDIA_NEW_PARAMETER_VALUE:
|
||||
case B_MEDIA_NODE_STOPPED:
|
||||
return node_specific;
|
||||
|
||||
|
||||
// everything else is invalid
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace notifications
|
||||
}; // namespace media
|
||||
}; // namespace BPrivate
|
||||
} // namespace notifications
|
||||
} // namespace media
|
||||
} // namespace BPrivate
|
||||
|
||||
+262
-201
@@ -1,213 +1,241 @@
|
||||
/***********************************************************************
|
||||
* Copyright (c) 2002 Marcus Overhagen. All Rights Reserved.
|
||||
* This file may be used under the terms of the OpenBeOS License.
|
||||
*
|
||||
* Used for BBufferGroup and BBuffer management across teams
|
||||
***********************************************************************/
|
||||
#include <Buffer.h>
|
||||
/*
|
||||
* Copyright 2009, Axel Dörfler, [email protected].
|
||||
* Copyright 2002, Marcus Overhagen. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
/*! 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 "SharedBufferList.h"
|
||||
|
||||
#include <Buffer.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
status_t
|
||||
_shared_buffer_list::Init()
|
||||
namespace BPrivate {
|
||||
|
||||
|
||||
/*static*/ area_id
|
||||
SharedBufferList::Create(SharedBufferList** _list)
|
||||
{
|
||||
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++) {
|
||||
info[i].id = -1;
|
||||
info[i].buffer = 0;
|
||||
info[i].reclaim_sem = 0;
|
||||
info[i].reclaimed = false;
|
||||
size_t size = (sizeof(SharedBufferList) + (B_PAGE_SIZE - 1))
|
||||
& ~(B_PAGE_SIZE - 1);
|
||||
SharedBufferList* list;
|
||||
|
||||
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();
|
||||
// if id == -1, we are in the media_server team,
|
||||
// and create the initial list, else we clone it
|
||||
// TODO: map this only once per team!
|
||||
|
||||
_shared_buffer_list *adr;
|
||||
status_t status;
|
||||
|
||||
if (id == -1) {
|
||||
size_t size = ((sizeof(_shared_buffer_list)) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1);
|
||||
status = create_area("shared buffer list",(void **)&adr,B_ANY_ADDRESS,size,B_LAZY_LOCK,B_READ_AREA | B_WRITE_AREA);
|
||||
if (status >= B_OK) {
|
||||
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));
|
||||
}
|
||||
SharedBufferList* list;
|
||||
area_id area = clone_area("shared buffer list clone", (void**)&list,
|
||||
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, id);
|
||||
if (area < 0) {
|
||||
ERROR("SharedBufferList::Clone() clone area: %ld err = %s\n", id,
|
||||
strerror(area));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (status < B_OK) ? NULL : adr;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_shared_buffer_list::Unmap()
|
||||
SharedBufferList::Put()
|
||||
{
|
||||
CALLED();
|
||||
// unmap the memory used by this struct
|
||||
// XXX is this save?
|
||||
area_id id;
|
||||
id = area_for(this);
|
||||
if (id >= B_OK)
|
||||
delete_area(id);
|
||||
|
||||
area_id area = area_for(this);
|
||||
if (area >= 0)
|
||||
delete_area(area);
|
||||
}
|
||||
|
||||
|
||||
/*! Deletes all BBuffers of the group specified by \a groupReclaimSem, then
|
||||
unmaps the list from memory.
|
||||
*/
|
||||
void
|
||||
_shared_buffer_list::Terminate(sem_id group_reclaim_sem)
|
||||
SharedBufferList::DeleteGroupAndPut(sem_id groupReclaimSem)
|
||||
{
|
||||
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
|
||||
// but at least try to unmap the memory
|
||||
Unmap();
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
// Decrement buffer count by one, and fill the gap
|
||||
// in the list with its last entry
|
||||
fCount--;
|
||||
if (fCount > 0)
|
||||
fInfos[i--] = fInfos[fCount];
|
||||
}
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
|
||||
Unmap();
|
||||
|
||||
Put();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_shared_buffer_list::Lock()
|
||||
{
|
||||
if (atomic_add(&locker_atom, 1) > 0) {
|
||||
SharedBufferList::Lock()
|
||||
{
|
||||
if (atomic_add(&fAtom, 1) > 0) {
|
||||
status_t status;
|
||||
while (B_INTERRUPTED == (status = acquire_sem(locker_sem)))
|
||||
;
|
||||
return status; // will only return != B_OK if the media_server crashed or quit
|
||||
do {
|
||||
status = acquire_sem(fSemaphore);
|
||||
} while (status == B_INTERRUPTED);
|
||||
|
||||
return status;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_shared_buffer_list::Unlock()
|
||||
{
|
||||
if (atomic_add(&locker_atom, -1) > 1)
|
||||
return release_sem(locker_sem); // will only return != B_OK if the media_server crashed or quit
|
||||
SharedBufferList::Unlock()
|
||||
{
|
||||
if (atomic_add(&fAtom, -1) > 1)
|
||||
return release_sem(fSemaphore);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_shared_buffer_list::AddBuffer(sem_id group_reclaim_sem, BBuffer *buffer)
|
||||
SharedBufferList::AddBuffer(sem_id groupReclaimSem, BBuffer* buffer)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
|
||||
if (buffer == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (Lock() != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (buffercount == MAX_BUFFER) {
|
||||
status_t status = Lock();
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (fCount == kMaxBuffers) {
|
||||
Unlock();
|
||||
debugger("we are doomed");
|
||||
return B_ERROR;
|
||||
return B_MEDIA_TOO_MANY_BUFFERS;
|
||||
}
|
||||
|
||||
info[buffercount].id = buffer->ID();
|
||||
info[buffercount].buffer = buffer;
|
||||
info[buffercount].reclaim_sem = group_reclaim_sem;
|
||||
info[buffercount].reclaimed = true;
|
||||
buffercount++;
|
||||
fInfos[fCount].id = buffer->ID();
|
||||
fInfos[fCount].buffer = buffer;
|
||||
fInfos[fCount].reclaim_sem = groupReclaimSem;
|
||||
fInfos[fCount].reclaimed = true;
|
||||
fCount++;
|
||||
|
||||
status_t status1 = release_sem_etc(group_reclaim_sem,1,B_DO_NOT_RESCHEDULE);
|
||||
status_t status2 = Unlock();
|
||||
status = release_sem_etc(groupReclaimSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return (status1 == B_OK && status2 == B_OK) ? B_OK : B_ERROR;
|
||||
return Unlock();
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
status_t
|
||||
SharedBufferList::RequestBuffer(sem_id groupReclaimSem, int32 buffersInGroup,
|
||||
size_t size, media_buffer_id wantID, BBuffer** _buffer, bigtime_t timeout)
|
||||
{
|
||||
CALLED();
|
||||
// we always search for a buffer from the group indicated by group_reclaim_sem first
|
||||
// if "size" != 0, we search for a buffer that is "size" bytes or larger
|
||||
// if "wantID" != 0, we search for a buffer with this id
|
||||
// if "*buffer" != NULL, we search for a buffer at this address
|
||||
// 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 acquire_flags;
|
||||
int32 count;
|
||||
// We always search for a buffer from the group indicated by groupReclaimSem
|
||||
// first.
|
||||
// If "size" != 0, we search for a buffer that is "size" bytes or larger.
|
||||
// If "wantID" != 0, we search for a buffer with this ID.
|
||||
// If "*_buffer" != NULL, we search for a buffer at this address.
|
||||
//
|
||||
// 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
|
||||
|
||||
uint32 acquireFlags;
|
||||
|
||||
if (timeout <= 0) {
|
||||
timeout = 0;
|
||||
acquire_flags = B_RELATIVE_TIMEOUT;
|
||||
} else if (timeout != B_INFINITE_TIMEOUT) {
|
||||
timeout += system_time();
|
||||
acquire_flags = B_ABSOLUTE_TIMEOUT;
|
||||
acquireFlags = B_RELATIVE_TIMEOUT;
|
||||
} else if (timeout == B_INFINITE_TIMEOUT) {
|
||||
acquireFlags = B_RELATIVE_TIMEOUT;
|
||||
} else {
|
||||
//timeout is B_INFINITE_TIMEOUT
|
||||
acquire_flags = B_RELATIVE_TIMEOUT;
|
||||
timeout += system_time();
|
||||
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
|
||||
count = 1;
|
||||
|
||||
|
||||
// With each itaration we request one more buffer, since we need to skip
|
||||
// the buffers that don't fit the request
|
||||
int32 count = 1;
|
||||
|
||||
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)
|
||||
return status;
|
||||
|
||||
// try to exit savely if the lock fails
|
||||
if (Lock() != B_OK) {
|
||||
ERROR("_shared_buffer_list:: RequestBuffer: Lock failed\n");
|
||||
release_sem_etc(group_reclaim_sem, count, 0);
|
||||
// try to exit savely if the lock fails
|
||||
status = Lock();
|
||||
if (status != B_OK) {
|
||||
ERROR("SharedBufferList:: RequestBuffer: Lock failed: %s\n",
|
||||
strerror(status));
|
||||
release_sem_etc(groupReclaimSem, count, 0);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < buffercount; i++) {
|
||||
// we need a BBuffer from the group, and it must be marked as reclaimed
|
||||
if (info[i].reclaim_sem == group_reclaim_sem && info[i].reclaimed) {
|
||||
if (
|
||||
(size != 0 && size <= info[i].buffer->SizeAvailable()) ||
|
||||
(*buffer != 0 && info[i].buffer == *buffer) ||
|
||||
(wantID != 0 && info[i].id == wantID)
|
||||
) {
|
||||
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
// We need a BBuffer from the group, and it must be marked as
|
||||
// reclaimed
|
||||
if (fInfos[i].reclaim_sem == groupReclaimSem
|
||||
&& fInfos[i].reclaimed) {
|
||||
if ((size != 0 && size <= fInfos[i].buffer->SizeAvailable())
|
||||
|| (*_buffer != 0 && fInfos[i].buffer == *_buffer)
|
||||
|| (wantID != 0 && fInfos[i].id == wantID)) {
|
||||
// we found a buffer
|
||||
info[i].reclaimed = false;
|
||||
*buffer = info[i].buffer;
|
||||
fInfos[i].reclaimed = false;
|
||||
*_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
|
||||
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();
|
||||
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) {
|
||||
ERROR("_shared_buffer_list:: RequestBuffer: unlock failed\n");
|
||||
ERROR("SharedBufferList:: RequestBuffer: unlock failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
// prepare to request one more buffer next time
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
_shared_buffer_list::RecycleBuffer(BBuffer *buffer)
|
||||
SharedBufferList::RecycleBuffer(BBuffer* buffer)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
int reclaimed_count;
|
||||
|
||||
// media_buffer_id id = buffer->ID();
|
||||
media_buffer_id id = buffer->fBufferID;
|
||||
|
||||
media_buffer_id id = buffer->ID();
|
||||
|
||||
if (Lock() != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
reclaimed_count = 0;
|
||||
for (int32 i = 0; i < buffercount; i++) {
|
||||
int32 reclaimedCount = 0;
|
||||
|
||||
for (int32 i = 0; i < fCount; i++) {
|
||||
// find the buffer id, and reclaim it in all groups it belongs to
|
||||
if (info[i].id == id) {
|
||||
reclaimed_count++;
|
||||
if (info[i].reclaimed) {
|
||||
ERROR("_shared_buffer_list::RecycleBuffer, BBuffer %p, id = %ld already reclaimed\n", buffer, id);
|
||||
if (fInfos[i].id == id) {
|
||||
reclaimedCount++;
|
||||
if (fInfos[i].reclaimed) {
|
||||
ERROR("SharedBufferList::RecycleBuffer, BBuffer %p, id = %ld "
|
||||
"already reclaimed\n", buffer, id);
|
||||
DEBUG_ONLY(debugger("buffer already reclaimed"));
|
||||
continue;
|
||||
}
|
||||
info[i].reclaimed = true;
|
||||
release_sem_etc(info[i].reclaim_sem, 1, B_DO_NOT_RESCHEDULE);
|
||||
fInfos[i].reclaimed = true;
|
||||
release_sem_etc(fInfos[i].reclaim_sem, 1, B_DO_NOT_RESCHEDULE);
|
||||
}
|
||||
}
|
||||
|
||||
if (Unlock() != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (reclaimed_count == 0) {
|
||||
ERROR("shared_buffer_list::RecycleBuffer, BBuffer %p, id = %ld NOT reclaimed\n", buffer, id);
|
||||
|
||||
if (reclaimedCount == 0) {
|
||||
ERROR("shared_buffer_list::RecycleBuffer, BBuffer %p, id = %ld NOT "
|
||||
"reclaimed\n", buffer, id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
_shared_buffer_list::GetBufferList(sem_id group_reclaim_sem, int32 buf_count, BBuffer **out_buffers)
|
||||
|
||||
/*! Returns exactly \a bufferCount buffers from the group specified via its
|
||||
\a groupReclaimSem if successful.
|
||||
*/
|
||||
status_t
|
||||
SharedBufferList::GetBufferList(sem_id groupReclaimSem, int32 bufferCount,
|
||||
BBuffer** buffers)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
int32 found;
|
||||
|
||||
found = 0;
|
||||
|
||||
if (Lock() != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
for (int32 i = 0; i < buffercount; i++)
|
||||
if (info[i].reclaim_sem == group_reclaim_sem) {
|
||||
out_buffers[found++] = info[i].buffer;
|
||||
if (found == buf_count)
|
||||
int32 found = 0;
|
||||
|
||||
for (int32 i = 0; i < fCount; i++)
|
||||
if (fInfos[i].reclaim_sem == groupReclaimSem) {
|
||||
buffers[found++] = fInfos[i].buffer;
|
||||
if (found == bufferCount)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (Unlock() != B_OK)
|
||||
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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
||||
* Copyright 2009, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
@@ -15,28 +15,30 @@
|
||||
|
||||
BufferManager::BufferManager()
|
||||
:
|
||||
fSharedBufferList(_shared_buffer_list::Clone()),
|
||||
fSharedBufferList(NULL),
|
||||
fSharedBufferListArea(-1),
|
||||
fNextBufferID(1),
|
||||
fLocker("buffer manager locker")
|
||||
{
|
||||
fSharedBufferListID = area_for(fSharedBufferList);
|
||||
fSharedBufferListArea
|
||||
= BPrivate::SharedBufferList::Create(&fSharedBufferList);
|
||||
}
|
||||
|
||||
|
||||
BufferManager::~BufferManager()
|
||||
{
|
||||
fSharedBufferList->Unmap();
|
||||
fSharedBufferList->Put();
|
||||
}
|
||||
|
||||
|
||||
area_id
|
||||
BufferManager::SharedBufferListID()
|
||||
BufferManager::SharedBufferListArea()
|
||||
{
|
||||
return fSharedBufferListID;
|
||||
return fSharedBufferListArea;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
status_t
|
||||
BufferManager::RegisterBuffer(team_id team, media_buffer_id bufferID,
|
||||
size_t* _size, int32* _flags, size_t* _offset, area_id* _area)
|
||||
{
|
||||
@@ -55,7 +57,7 @@ BufferManager::RegisterBuffer(team_id team, media_buffer_id bufferID,
|
||||
|
||||
*_area = info->area;
|
||||
*_offset = info->offset;
|
||||
*_size = info->size,
|
||||
*_size = info->size,
|
||||
*_flags = info->flags;
|
||||
|
||||
return B_OK;
|
||||
@@ -69,7 +71,7 @@ BufferManager::RegisterBuffer(team_id team, size_t size, int32 flags,
|
||||
BAutolock lock(fLocker);
|
||||
TRACE("RegisterBuffer team = %ld, area = %ld, offset = %ld, size = %ld\n",
|
||||
team, area, offset, size);
|
||||
|
||||
|
||||
area_id clonedArea = _CloneArea(area);
|
||||
if (clonedArea < 0) {
|
||||
ERROR("RegisterBuffer: failed to clone buffer! error = %#lx, team = "
|
||||
@@ -84,14 +86,19 @@ BufferManager::RegisterBuffer(team_id team, size_t size, int32 flags,
|
||||
info.offset = offset;
|
||||
info.size = size;
|
||||
info.flags = flags;
|
||||
info.teams.insert(team);
|
||||
|
||||
*_bufferID = info.id;
|
||||
|
||||
fBufferInfoMap.Put(info.id, info);
|
||||
try {
|
||||
info.teams.insert(team);
|
||||
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);
|
||||
|
||||
*_bufferID = info.id;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -100,12 +107,12 @@ status_t
|
||||
BufferManager::UnregisterBuffer(team_id team, media_buffer_id bufferID)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
TRACE("UnregisterBuffer: team = %ld, bufferid = %ld\n", team, bufferID);
|
||||
TRACE("UnregisterBuffer: team = %ld, bufferID = %ld\n", team, bufferID);
|
||||
|
||||
buffer_info* info;
|
||||
if (!fBufferInfoMap.Get(bufferID, info)) {
|
||||
ERROR("UnregisterBuffer: failed to unregister buffer! team = %ld, "
|
||||
"bufferid = %ld\n", team, bufferID);
|
||||
"bufferID = %ld\n", team, bufferID);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -114,7 +121,7 @@ BufferManager::UnregisterBuffer(team_id team, media_buffer_id bufferID)
|
||||
"bufferID = %ld\n", team, bufferID);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
info->teams.erase(team);
|
||||
|
||||
TRACE("UnregisterBuffer: team = %ld removed from bufferID = %ld\n", team,
|
||||
@@ -146,7 +153,7 @@ BufferManager::CleanupTeam(team_id team)
|
||||
|
||||
if (entry.value.teams.empty()) {
|
||||
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);
|
||||
iterator.Remove();
|
||||
}
|
||||
@@ -182,14 +189,16 @@ BufferManager::Dump()
|
||||
area_id
|
||||
BufferManager::_CloneArea(area_id area)
|
||||
{
|
||||
clone_info* info;
|
||||
if (fCloneInfoMap.Get(area, info)) {
|
||||
// we have already cloned this particular area
|
||||
TRACE("BufferManager::_CloneArea() area %ld has already been cloned "
|
||||
"(id %ld)\n", area, info->clone);
|
||||
{
|
||||
clone_info* info;
|
||||
if (fCloneInfoMap.Get(area, info)) {
|
||||
// we have already cloned this particular area
|
||||
TRACE("BufferManager::_CloneArea() area %ld has already been "
|
||||
"cloned (id %ld)\n", area, info->clone);
|
||||
|
||||
info->ref_count++;
|
||||
return info->clone;
|
||||
info->ref_count++;
|
||||
return info->clone;
|
||||
}
|
||||
}
|
||||
|
||||
void* address;
|
||||
@@ -199,16 +208,22 @@ BufferManager::_CloneArea(area_id area)
|
||||
TRACE("BufferManager::_CloneArea() cloned area %ld, clone id %ld\n",
|
||||
area, clonedArea);
|
||||
|
||||
if (clonedArea >= 0) {
|
||||
clone_info info;
|
||||
info.clone = clonedArea;
|
||||
info.ref_count = 1;
|
||||
if (clonedArea < 0)
|
||||
return clonedArea;
|
||||
|
||||
fCloneInfoMap.Put(area, info);
|
||||
fSourceInfoMap.Put(clonedArea, area);
|
||||
clone_info info;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
||||
* Copyright 2009, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
@@ -13,16 +13,18 @@
|
||||
#include <HashMap.h>
|
||||
|
||||
|
||||
struct _shared_buffer_list;
|
||||
namespace BPrivate {
|
||||
class SharedBufferList;
|
||||
}
|
||||
|
||||
|
||||
class BufferManager {
|
||||
public:
|
||||
BufferManager();
|
||||
~BufferManager();
|
||||
|
||||
area_id SharedBufferListID();
|
||||
|
||||
|
||||
area_id SharedBufferListArea();
|
||||
|
||||
status_t RegisterBuffer(team_id team,
|
||||
media_buffer_id bufferID, size_t* _size,
|
||||
int32* _flags, size_t* _offset, area_id* _area);
|
||||
@@ -56,7 +58,7 @@ private:
|
||||
int32 flags;
|
||||
std::set<team_id> teams;
|
||||
};
|
||||
|
||||
|
||||
template<typename Type> struct id_hash {
|
||||
id_hash()
|
||||
:
|
||||
@@ -84,7 +86,7 @@ private:
|
||||
{
|
||||
return fID;
|
||||
}
|
||||
|
||||
|
||||
id_hash& operator=(const id_hash& other)
|
||||
{
|
||||
fID = other.fID;
|
||||
@@ -99,8 +101,8 @@ private:
|
||||
typedef HashMap<id_hash<area_id>, clone_info> CloneInfoMap;
|
||||
typedef HashMap<id_hash<area_id>, area_id> SourceInfoMap;
|
||||
|
||||
_shared_buffer_list* fSharedBufferList;
|
||||
area_id fSharedBufferListID;
|
||||
BPrivate::SharedBufferList* fSharedBufferList;
|
||||
area_id fSharedBufferListArea;
|
||||
media_buffer_id fNextBufferID;
|
||||
BLocker fLocker;
|
||||
BufferInfoMap fBufferInfoMap;
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2002, 2003 Marcus Overhagen, Jérôme Duval. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "DefaultManager.h"
|
||||
|
||||
#include <Application.h>
|
||||
#include <Directory.h>
|
||||
#include <File.h>
|
||||
@@ -12,7 +16,7 @@
|
||||
#include <Path.h>
|
||||
#include <TimeSource.h>
|
||||
#include <string.h>
|
||||
#include "DefaultManager.h"
|
||||
|
||||
#include "DormantNodeManager.h"
|
||||
#include "NodeManager.h"
|
||||
#include "debug.h"
|
||||
@@ -74,12 +78,12 @@ DefaultManager::LoadState()
|
||||
BPath path;
|
||||
if((err = find_directory(B_USER_SETTINGS_DIRECTORY, &path))!=B_OK)
|
||||
return err;
|
||||
|
||||
|
||||
path.Append(kDefaultManagerSettingsDirectory);
|
||||
path.Append(kDefaultManagerSettingsFile);
|
||||
|
||||
|
||||
BFile file(path.Path(), B_READ_ONLY);
|
||||
|
||||
|
||||
uint32 category_count;
|
||||
if (file.Read(fBeginHeader, sizeof(uint32)*3) < (int32)sizeof(uint32)*3)
|
||||
return B_ERROR;
|
||||
@@ -119,20 +123,20 @@ DefaultManager::SaveState(NodeManager *node_manager)
|
||||
if ((err = create_directory(path.Path(), 0755)) != B_OK)
|
||||
return err;
|
||||
path.Append(kDefaultManagerSettingsFile);
|
||||
|
||||
|
||||
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
|
||||
|
||||
|
||||
uint32 default_types[] = {kMsgTypeVideoIn, kMsgTypeVideoOut, kMsgTypeAudioIn, kMsgTypeAudioOut};
|
||||
uint32 media_node_ids[] = {fPhysicalVideoIn, fPhysicalVideoOut, fPhysicalAudioIn, fPhysicalAudioOut};
|
||||
for (uint32 i=0; i<sizeof(default_types)/sizeof(default_types[0]); i++) {
|
||||
BMessage *settings = new BMessage();
|
||||
settings->AddInt32(kDefaultManagerType, default_types[i]);
|
||||
|
||||
|
||||
// we call the node manager to have more infos about nodes
|
||||
dormant_node_info info;
|
||||
media_node node;
|
||||
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;
|
||||
if (node_manager->GetDormantNodeInfo(&info, node) != B_OK)
|
||||
continue;
|
||||
@@ -147,17 +151,17 @@ DefaultManager::SaveState(NodeManager *node_manager)
|
||||
settings->AddInt32(kDefaultManagerInput, default_types[i] == kMsgTypeAudioOut ? fPhysicalAudioOutInputID : 0);
|
||||
settings->AddString(kDefaultManagerFlavorName, info.name);
|
||||
settings->AddString(kDefaultManagerPath, path.Path());
|
||||
|
||||
|
||||
list.AddItem(settings);
|
||||
TRACE("message %s added\n", info.name);
|
||||
}
|
||||
|
||||
|
||||
if (file.Write(fBeginHeader, sizeof(uint32)*3) < (int32)sizeof(uint32)*3)
|
||||
return B_ERROR;
|
||||
int32 category_count = list.CountItems();
|
||||
if (file.Write(&category_count, sizeof(uint32)) < (int32)sizeof(uint32))
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
for (int32 i = 0; i < category_count; i++) {
|
||||
BMessage *settings = (BMessage *)list.ItemAt(i);
|
||||
uint32 default_type;
|
||||
@@ -173,7 +177,7 @@ DefaultManager::SaveState(NodeManager *node_manager)
|
||||
}
|
||||
if (file.Write(fEndHeader, sizeof(uint32)*3) < (int32)sizeof(uint32)*3)
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -201,14 +205,14 @@ DefaultManager::Set(media_node_id node_id, const char *input_name, int32 input_i
|
||||
return B_OK;
|
||||
case TIME_SOURCE:
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
case SYSTEM_TIME_SOURCE: //called by the media_server's ServerApp::StartSystemTimeSource()
|
||||
{
|
||||
ASSERT(fSystemTimeSource == -1);
|
||||
fSystemTimeSource = node_id;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
ERROR("DefaultManager::Set Error: called with unknown type %d\n", type);
|
||||
@@ -233,7 +237,7 @@ DefaultManager::Get(media_node_id *nodeid, char *input_name, int32 *inputid, nod
|
||||
return B_NAME_NOT_FOUND;
|
||||
*nodeid = fPhysicalAudioIn;
|
||||
return B_OK;
|
||||
|
||||
|
||||
case VIDEO_OUTPUT: // output: nodeid
|
||||
if (fPhysicalVideoOut == -1)
|
||||
return B_NAME_NOT_FOUND;
|
||||
@@ -266,7 +270,7 @@ DefaultManager::Get(media_node_id *nodeid, char *input_name, int32 *inputid, nod
|
||||
else
|
||||
*nodeid = fSystemTimeSource;
|
||||
return B_OK;
|
||||
|
||||
|
||||
case SYSTEM_TIME_SOURCE:
|
||||
*nodeid = fSystemTimeSource;
|
||||
return B_OK;
|
||||
@@ -299,7 +303,7 @@ void
|
||||
DefaultManager::RescanThread()
|
||||
{
|
||||
printf("DefaultManager::RescanThread() enter\n");
|
||||
|
||||
|
||||
// We do not search for the system time source,
|
||||
// it should already exist
|
||||
ASSERT(fSystemTimeSource != -1);
|
||||
@@ -307,7 +311,7 @@ DefaultManager::RescanThread()
|
||||
if (fPhysicalVideoOut == -1) {
|
||||
FindPhysical(&fPhysicalVideoOut, kMsgTypeVideoOut, false, B_MEDIA_RAW_VIDEO);
|
||||
FindPhysical(&fPhysicalVideoOut, kMsgTypeVideoOut, false, B_MEDIA_ENCODED_VIDEO);
|
||||
}
|
||||
}
|
||||
if (fPhysicalVideoIn == -1) {
|
||||
FindPhysical(&fPhysicalVideoIn, kMsgTypeVideoIn, true, B_MEDIA_RAW_VIDEO);
|
||||
FindPhysical(&fPhysicalVideoIn, kMsgTypeVideoIn, true, B_MEDIA_ENCODED_VIDEO);
|
||||
@@ -332,7 +336,7 @@ DefaultManager::RescanThread()
|
||||
} else {
|
||||
ERROR("DefaultManager: Did not try to connect mixer and soundcard\n");
|
||||
}
|
||||
|
||||
|
||||
addonserver_rescan_finished_notify_command cmd;
|
||||
SendToAddonServer(ADDONSERVER_RESCAN_FINISHED_NOTIFY, &cmd, sizeof(cmd));
|
||||
|
||||
@@ -375,8 +379,8 @@ DefaultManager::FindPhysical(volatile media_node_id *id, uint32 default_type, bo
|
||||
memset(&format, 0, sizeof(format));
|
||||
format.type = type;
|
||||
count = MAX_NODE_INFOS;
|
||||
rv = BMediaRoster::Roster()->GetLiveNodes(&info[0], &count,
|
||||
isInput ? NULL : &format, isInput ? &format : NULL, NULL,
|
||||
rv = BMediaRoster::Roster()->GetLiveNodes(&info[0], &count,
|
||||
isInput ? NULL : &format, isInput ? &format : NULL, NULL,
|
||||
isInput ? B_BUFFER_PRODUCER | B_PHYSICAL_INPUT : B_BUFFER_CONSUMER | B_PHYSICAL_OUTPUT);
|
||||
if (rv != B_OK || count < 1) {
|
||||
ERROR("Couldn't find physical %s %s node\n", isAudio ? "audio" : "video", isInput ? "input" : "output");
|
||||
@@ -384,7 +388,7 @@ DefaultManager::FindPhysical(volatile media_node_id *id, uint32 default_type, bo
|
||||
}
|
||||
for (int i = 0; i < count; i++)
|
||||
TRACE("info[%d].name %s\n", i, info[i].name);
|
||||
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (isAudio) {
|
||||
if (isInput) {
|
||||
@@ -406,7 +410,7 @@ DefaultManager::FindPhysical(volatile media_node_id *id, uint32 default_type, bo
|
||||
if (0 == strcmp(info[i].name, "DV Output")) // skip the Firewire audio driver
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(msg) { // we have a default info msg
|
||||
dormant_node_info dninfo;
|
||||
if(BMediaRoster::Roster()->GetDormantNodeFor(info[i].node, &dninfo) != B_OK) {
|
||||
@@ -419,13 +423,13 @@ DefaultManager::FindPhysical(volatile media_node_id *id, uint32 default_type, bo
|
||||
continue;
|
||||
}
|
||||
BPath path;
|
||||
if((_DormantNodeManager->FindAddonPath(&path, dninfo.addon)!=B_OK)
|
||||
if((_DormantNodeManager->FindAddonPath(&path, dninfo.addon)!=B_OK)
|
||||
|| (path != msgPath)) {
|
||||
ERROR("Doesn't match : path\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
TRACE("Default physical %s %s \"%s\" created!\n",
|
||||
TRACE("Default physical %s %s \"%s\" created!\n",
|
||||
isAudio ? "audio" : "video", isInput ? "input" : "output", info[i].name);
|
||||
*id = info[i].node.node;
|
||||
if(msg && isAudio && !isInput)
|
||||
@@ -442,7 +446,7 @@ DefaultManager::FindTimeSource()
|
||||
media_format input; /* a physical audio output has a logical data input (DAC)*/
|
||||
int32 count;
|
||||
status_t rv;
|
||||
|
||||
|
||||
/* First try to use the current default physical audio out
|
||||
*/
|
||||
if (fPhysicalAudioOut != -1) {
|
||||
@@ -462,7 +466,7 @@ DefaultManager::FindTimeSource()
|
||||
} else {
|
||||
printf("Default DAC node does not exist!\n");
|
||||
}
|
||||
|
||||
|
||||
/* Now try to find another physical audio out node
|
||||
*/
|
||||
memset(&input, 0, sizeof(input));
|
||||
@@ -472,7 +476,7 @@ DefaultManager::FindTimeSource()
|
||||
if (rv == B_OK && count >= 1) {
|
||||
for (int i = 0; i < count; i++)
|
||||
printf("info[%d].name %s\n", i, info[i].name);
|
||||
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
// The BeOS R5 None Out node pretend to be a physical time source, that is pretty dumb
|
||||
if (0 == strcmp(info[i].name, "None Out")) // skip the Null audio driver
|
||||
@@ -486,8 +490,8 @@ DefaultManager::FindTimeSource()
|
||||
}
|
||||
} else {
|
||||
printf("Couldn't find DAC timesource node\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* XXX we might use other audio or video clock timesources
|
||||
*/
|
||||
}
|
||||
@@ -526,7 +530,7 @@ DefaultManager::ConnectMixerToOutput()
|
||||
bigtime_t start_at;
|
||||
int32 count;
|
||||
status_t rv;
|
||||
|
||||
|
||||
roster = BMediaRoster::Roster();
|
||||
|
||||
rv = roster->GetNodeFor(fPhysicalAudioOut, &soundcard);
|
||||
@@ -558,13 +562,13 @@ DefaultManager::ConnectMixerToOutput()
|
||||
rv = B_ERROR;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
input = inputs[i];
|
||||
if(input.destination.id == fPhysicalAudioOutInputID)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
@@ -636,13 +640,13 @@ DefaultManager::ConnectMixerToOutput()
|
||||
roster->SetTimeSourceFor(soundcard.node, timesource.node);
|
||||
roster->PrerollNode(mixer);
|
||||
roster->PrerollNode(soundcard);
|
||||
|
||||
|
||||
ts = roster->MakeTimeSourceFor(mixer);
|
||||
start_at = ts->Now() + 50000;
|
||||
roster->StartNode(mixer, start_at);
|
||||
roster->StartNode(soundcard, start_at);
|
||||
ts->Release();
|
||||
|
||||
|
||||
finish:
|
||||
roster->ReleaseNode(mixer);
|
||||
roster->ReleaseNode(soundcard);
|
||||
|
||||
@@ -77,7 +77,7 @@ NodeManager::RegisterNode(media_node_id *nodeid, media_addon_id addon_id, int32
|
||||
BAutolock lock(fLocker);
|
||||
bool b;
|
||||
registered_node rn;
|
||||
rn.nodeid = fNextNodeID;
|
||||
rn.node_id = fNextNodeID;
|
||||
rn.addon_id = addon_id;
|
||||
rn.addon_flavor_id = addon_flavor_id;
|
||||
strcpy(rn.name, name);
|
||||
@@ -87,7 +87,7 @@ NodeManager::RegisterNode(media_node_id *nodeid, media_addon_id addon_id, int32
|
||||
rn.creator = -1; // will be set later
|
||||
rn.globalrefcount = 1;
|
||||
rn.teamrefcount.Insert(team, 1);
|
||||
|
||||
|
||||
b = fRegisteredNodeMap->Insert(fNextNodeID, rn);
|
||||
ASSERT(b);
|
||||
*nodeid = fNextNodeID;
|
||||
@@ -194,12 +194,12 @@ NodeManager::DecrementGlobalRefCount(media_node_id nodeid, team_id team)
|
||||
ASSERT(b);
|
||||
}
|
||||
rn->globalrefcount -= 1;
|
||||
|
||||
|
||||
if (rn->globalrefcount == 0) {
|
||||
printf("NodeManager::DecrementGlobalRefCount: detected released node is now unused, node %ld\n", nodeid);
|
||||
FinalReleaseNode(nodeid);
|
||||
}
|
||||
|
||||
|
||||
TRACE("NodeManager::DecrementGlobalRefCount leave: node %ld, team %ld, count %ld, globalcount %ld\n", nodeid, team, debug_count, rn->globalrefcount);
|
||||
return B_OK;
|
||||
}
|
||||
@@ -218,12 +218,12 @@ NodeManager::SetNodeCreator(media_node_id nodeid, team_id creator)
|
||||
ERROR("NodeManager::SetNodeCreator: node %ld not found\n", nodeid);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (rn->creator != -1) {
|
||||
ERROR("NodeManager::SetNodeCreator: node %ld is already assigned creator %ld\n", nodeid, rn->creator);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
rn->creator = creator;
|
||||
return B_OK;
|
||||
}
|
||||
@@ -253,47 +253,52 @@ NodeManager::FinalReleaseNode(media_node_id nodeid)
|
||||
|
||||
|
||||
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);
|
||||
registered_node *rn;
|
||||
bool b;
|
||||
TRACE("NodeManager::GetCloneForId enter: node %ld team %ld\n", nodeid, team);
|
||||
TRACE("NodeManager::GetCloneForID enter: node %ld team %ld\n", nodeID,
|
||||
team);
|
||||
|
||||
if (B_OK != IncrementGlobalRefCount(nodeid, team)) {
|
||||
ERROR("NodeManager::GetCloneForId: couldn't increment ref count, node %ld team %ld\n", nodeid, team);
|
||||
if (IncrementGlobalRefCount(nodeID, team) != B_OK) {
|
||||
ERROR("NodeManager::GetCloneForID: couldn't increment ref count, "
|
||||
"node %ld team %ld\n", nodeID, team);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
b = fRegisteredNodeMap->Get(nodeid, &rn);
|
||||
if (!b) {
|
||||
ERROR("NodeManager::GetCloneForId: node %ld not found\n", nodeid);
|
||||
DecrementGlobalRefCount(nodeid, team);
|
||||
registered_node* registeredNode;
|
||||
if (!fRegisteredNodeMap->Get(nodeID, ®isteredNode)) {
|
||||
ERROR("NodeManager::GetCloneForID: node %ld not found\n", nodeID);
|
||||
DecrementGlobalRefCount(nodeID, team);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
node->node = rn->nodeid;
|
||||
node->port = rn->port;
|
||||
node->kind = rn->kinds;
|
||||
node->node = registeredNode->node_id;
|
||||
node->port = registeredNode->port;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* This function locates the default "node" for the requested "type" and returnes a clone.
|
||||
* 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)
|
||||
*/
|
||||
/*! This function locates the default "node" for the requested "type" and
|
||||
returns a clone.
|
||||
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
|
||||
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);
|
||||
status_t status;
|
||||
media_node_id id;
|
||||
|
||||
TRACE("NodeManager::GetClone enter: team %ld, type %d (%s)\n", team, type, get_node_type(type));
|
||||
|
||||
|
||||
status = GetDefaultNode(&id, input_name, input_id, type);
|
||||
if (status != B_OK) {
|
||||
ERROR("NodeManager::GetClone: couldn't GetDefaultNode, team %ld, type %d (%s)\n", team, type, get_node_type(type));
|
||||
@@ -302,9 +307,9 @@ NodeManager::GetClone(media_node *node, char *input_name, int32 *input_id, node_
|
||||
}
|
||||
ASSERT(id > 0);
|
||||
|
||||
status = GetCloneForId(node, id, team);
|
||||
status = GetCloneForID(node, id, team);
|
||||
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;
|
||||
return status;
|
||||
}
|
||||
@@ -366,37 +371,39 @@ NodeManager::PublishOutputs(const media_node &node, const media_output *outputs,
|
||||
|
||||
|
||||
status_t
|
||||
NodeManager::FindNodeId(media_node_id *nodeid, port_id port)
|
||||
NodeManager::FindNodeID(media_node_id* nodeID, port_id port)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
registered_node *rn;
|
||||
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
|
||||
if (rn->port == port) {
|
||||
*nodeid = rn->nodeid;
|
||||
TRACE("NodeManager::FindNodeId found port %ld, node %ld\n", port, *nodeid);
|
||||
*nodeID = rn->node_id;
|
||||
TRACE("NodeManager::FindNodeID found port %ld, node %ld\n", port,
|
||||
*nodeID);
|
||||
return B_OK;
|
||||
}
|
||||
media_output *output;
|
||||
for (rn->outputlist.Rewind(); rn->outputlist.GetNext(&output); ) {
|
||||
if (output->source.port == port) {
|
||||
*nodeid = rn->nodeid;
|
||||
TRACE("NodeManager::FindNodeId found output port %ld, node %ld\n", port, *nodeid);
|
||||
*nodeID = rn->node_id;
|
||||
TRACE("NodeManager::FindNodeID found output port %ld, node %ld\n", port, *nodeid);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
media_input *input;
|
||||
for (rn->inputlist.Rewind(); rn->inputlist.GetNext(&input); ) {
|
||||
if (input->destination.port == port) {
|
||||
*nodeid = rn->nodeid;
|
||||
TRACE("NodeManager::FindNodeId found input port %ld, node %ld\n", port, *nodeid);
|
||||
*nodeID = rn->node_id;
|
||||
TRACE("NodeManager::FindNodeID found input port %ld, node %ld\n", port, *nodeid);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
ERROR("NodeManager::FindNodeId failed, port %ld\n", port);
|
||||
ERROR("NodeManager::FindNodeID failed, port %ld\n", port);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
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
|
||||
registered_node *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
|
||||
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;
|
||||
@@ -422,13 +429,14 @@ NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node &
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
NodeManager::GetLiveNodeInfo(live_node_info *live_info, const media_node &node)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
registered_node *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.kind & NODE_KIND_COMPARE_MASK) == (rn->kinds & NODE_KIND_COMPARE_MASK));
|
||||
live_info->node = node;
|
||||
@@ -451,7 +459,7 @@ NodeManager::GetInstances(media_node_id *node_ids, int32* count, int32 maxcount,
|
||||
*count = 0;
|
||||
for (fRegisteredNodeMap->Rewind(); (maxcount > 0) && fRegisteredNodeMap->GetNext(&rn); ) {
|
||||
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;
|
||||
maxcount -= 1;
|
||||
}
|
||||
@@ -467,7 +475,7 @@ NodeManager::GetLiveNodes(Stack<live_node_info> *livenodes, int32 maxcount, cons
|
||||
BAutolock lock(fLocker);
|
||||
registered_node *rn;
|
||||
int namelen;
|
||||
|
||||
|
||||
TRACE("NodeManager::GetLiveNodes: maxcount %ld, in-format %p, out-format %p, name %s, require_kinds 0x%Lx\n",
|
||||
maxcount, inputformat, outputformat, (name ? name : "NULL"), require_kinds);
|
||||
|
||||
@@ -513,7 +521,7 @@ NodeManager::GetLiveNodes(Stack<live_node_info> *livenodes, int32 maxcount, cons
|
||||
}
|
||||
|
||||
live_node_info lni;
|
||||
lni.node.node = rn->nodeid;
|
||||
lni.node.node = rn->node_id;
|
||||
lni.node.port = rn->port;
|
||||
lni.node.kind = rn->kinds;
|
||||
lni.hint_point = BPoint(0, 0);
|
||||
@@ -526,16 +534,17 @@ NodeManager::GetLiveNodes(Stack<live_node_info> *livenodes, int32 maxcount, cons
|
||||
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
|
||||
NodeManager::GetLiveNodes(BMessage *msg)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
registered_node *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;
|
||||
}
|
||||
@@ -544,16 +553,16 @@ NodeManager::GetLiveNodes(BMessage *msg)
|
||||
* Registration of BMediaAddOns
|
||||
**********************************************************************/
|
||||
|
||||
void
|
||||
void
|
||||
NodeManager::RegisterAddon(const entry_ref &ref, media_addon_id *newid)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
media_addon_id id;
|
||||
id = fNextAddOnID;
|
||||
fNextAddOnID += 1;
|
||||
|
||||
|
||||
printf("NodeManager::RegisterAddon: ref-name \"%s\", assigning id %ld\n", ref.name, id);
|
||||
|
||||
|
||||
fAddonPathMap->Insert(id, ref);
|
||||
*newid = id;
|
||||
}
|
||||
@@ -579,7 +588,7 @@ NodeManager::GetAddonRef(entry_ref *ref, media_addon_id id)
|
||||
*ref = *tempref;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -592,7 +601,7 @@ void
|
||||
NodeManager::AddDormantFlavorInfo(const dormant_flavor_info &dfi)
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
|
||||
|
||||
printf("NodeManager::AddDormantFlavorInfo, addon-id %ld, flavor-id %ld, name \"%s\", flavor-name \"%s\", flavor-info \"%s\"\n", dfi.node_info.addon, dfi.node_info.flavor_id, dfi.node_info.name, dfi.name, dfi.info);
|
||||
|
||||
// Try to find the addon-id/flavor-id in the list.
|
||||
@@ -670,8 +679,8 @@ NodeManager::IncrementAddonFlavorInstancesCount(media_addon_id addonid, int32 fl
|
||||
ERROR("NodeManager::IncrementAddonFlavorInstancesCount addonid %ld, flavorid %ld maximum (or more) instances already exist\n", addonid, flavorid);
|
||||
return B_ERROR; // maximum (or more) instances already exist
|
||||
}
|
||||
|
||||
bool b;
|
||||
|
||||
bool b;
|
||||
int32 *count;
|
||||
b = dafi->TeamInstancesCount.Get(team, &count);
|
||||
if (b) {
|
||||
@@ -697,7 +706,7 @@ NodeManager::DecrementAddonFlavorInstancesCount(media_addon_id addonid, int32 fl
|
||||
if (dafi->AddonID != addonid || dafi->AddonFlavorID != flavorid)
|
||||
continue;
|
||||
|
||||
bool b;
|
||||
bool b;
|
||||
int32 *count;
|
||||
b = dafi->TeamInstancesCount.Get(team, &count);
|
||||
if (!b) {
|
||||
@@ -728,7 +737,7 @@ NodeManager::CleanupDormantFlavorInfos()
|
||||
// XXX FlavorsChanged(media_addon_id addonid, int32 newcount, int32 gonecount)
|
||||
}
|
||||
|
||||
status_t
|
||||
status_t
|
||||
NodeManager::GetDormantNodes(dormant_node_info * out_info,
|
||||
int32 * io_count,
|
||||
const media_format * has_input /* = NULL */,
|
||||
@@ -751,7 +760,7 @@ NodeManager::GetDormantNodes(dormant_node_info * out_info,
|
||||
namelen = 0;
|
||||
}
|
||||
|
||||
maxcount = *io_count;
|
||||
maxcount = *io_count;
|
||||
*io_count = 0;
|
||||
for (fDormantAddonFlavorList->Rewind(); (*io_count < maxcount) && fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
if (!dafi->InfoValid)
|
||||
@@ -788,7 +797,7 @@ NodeManager::GetDormantNodes(dormant_node_info * out_info,
|
||||
if (!hasit)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
out_info[*io_count] = dfi->node_info;
|
||||
*io_count += 1;
|
||||
}
|
||||
@@ -796,7 +805,7 @@ NodeManager::GetDormantNodes(dormant_node_info * out_info,
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
status_t
|
||||
NodeManager::GetDormantFlavorInfoFor(media_addon_id addon,
|
||||
int32 flavor_id,
|
||||
dormant_flavor_info *outFlavor)
|
||||
@@ -807,7 +816,7 @@ NodeManager::GetDormantFlavorInfoFor(media_addon_id addon,
|
||||
if (dafi->AddonID == addon && dafi->AddonFlavorID == flavor_id && dafi->InfoValid == true) {
|
||||
*outFlavor = dafi->Info;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
||||
@@ -867,9 +876,9 @@ NodeManager::CleanupTeam(team_id team)
|
||||
PRINT(1, "NodeManager::CleanupTeam: team %ld\n", team);
|
||||
|
||||
// XXX send notifications after removing nodes
|
||||
|
||||
|
||||
// Cleanup node references
|
||||
|
||||
|
||||
registered_node *rn;
|
||||
for (fRegisteredNodeMap->Rewind(); fRegisteredNodeMap->GetNext(&rn); ) {
|
||||
// if the gone team was the creator of some global dormant node instance, we now invalidate that
|
||||
@@ -901,11 +910,11 @@ NodeManager::CleanupTeam(team_id team)
|
||||
fRegisteredNodeMap->RemoveCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Cleanup addon references
|
||||
dormant_addon_flavor_info *dafi;
|
||||
for (fDormantAddonFlavorList->Rewind(); fDormantAddonFlavorList->GetNext(&dafi); ) {
|
||||
bool b;
|
||||
bool b;
|
||||
int32 *count;
|
||||
b = dafi->TeamInstancesCount.Get(team, &count);
|
||||
if (b) {
|
||||
@@ -946,7 +955,7 @@ NodeManager::Dump()
|
||||
{
|
||||
BAutolock lock(fLocker);
|
||||
printf("\n");
|
||||
|
||||
|
||||
/* for each addon-id, the addon path map contains an entry_ref
|
||||
*/
|
||||
printf("NodeManager: addon path map follows:\n");
|
||||
@@ -966,7 +975,7 @@ NodeManager::Dump()
|
||||
registered_node *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",
|
||||
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): ");
|
||||
team_id *team;
|
||||
int32 *refcount;
|
||||
@@ -993,7 +1002,7 @@ NodeManager::Dump()
|
||||
printf("NodeManager: list end\n");
|
||||
printf("\n");
|
||||
|
||||
/*
|
||||
/*
|
||||
*/
|
||||
printf("NodeManager: dormant flavor list follows:\n");
|
||||
dormant_addon_flavor_info *dafi;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
struct registered_node {
|
||||
media_node_id nodeid;
|
||||
media_node_id node_id;
|
||||
media_addon_id addon_id;
|
||||
int32 addon_flavor_id;
|
||||
char name[B_MEDIA_NAME_LENGTH];
|
||||
@@ -26,11 +26,11 @@ struct registered_node {
|
||||
|
||||
struct dormant_addon_flavor_info {
|
||||
media_addon_id AddonID;
|
||||
int32 AddonFlavorID;
|
||||
int32 AddonFlavorID;
|
||||
|
||||
int32 MaxInstancesCount;
|
||||
int32 GlobalInstancesCount;
|
||||
|
||||
|
||||
Map<team_id, int32> TeamInstancesCount;
|
||||
|
||||
bool InfoValid;
|
||||
@@ -47,23 +47,24 @@ public:
|
||||
|
||||
status_t LoadState();
|
||||
status_t SaveState();
|
||||
|
||||
|
||||
void Dump();
|
||||
|
||||
/* 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 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();
|
||||
|
||||
/* 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 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 ReleaseNode(const media_node &node, team_id team);
|
||||
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 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 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);
|
||||
@@ -80,8 +81,8 @@ public:
|
||||
|
||||
void RegisterAddon(const entry_ref &ref, media_addon_id *newid);
|
||||
void UnregisterAddon(media_addon_id id);
|
||||
|
||||
void AddDormantFlavorInfo(const dormant_flavor_info &dfi);
|
||||
|
||||
void AddDormantFlavorInfo(const dormant_flavor_info &dfi);
|
||||
void InvalidateDormantFlavorInfo(media_addon_id id);
|
||||
void RemoveDormantFlavorInfo(media_addon_id id);
|
||||
void CleanupDormantFlavorInfos();
|
||||
@@ -103,11 +104,11 @@ public:
|
||||
dormant_flavor_info *outFlavor);
|
||||
|
||||
void CleanupTeam(team_id team);
|
||||
|
||||
|
||||
private:
|
||||
media_addon_id fNextAddOnID;
|
||||
media_node_id fNextNodeID;
|
||||
|
||||
|
||||
BLocker *fLocker;
|
||||
List<dormant_addon_flavor_info> *fDormantAddonFlavorList;
|
||||
Map<media_addon_id,entry_ref> *fAddonPathMap;
|
||||
|
||||
@@ -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
|
||||
@@ -27,10 +27,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* to comply with the license above, do not remove the following line */
|
||||
char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 "
|
||||
"Marcus Overhagen <[email protected]>";
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Application.h>
|
||||
#include <Autolock.h>
|
||||
@@ -40,9 +45,6 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 "
|
||||
#include <MediaFormats.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "AddOnManager.h"
|
||||
#include "AppManager.h"
|
||||
#include "BufferManager.h"
|
||||
@@ -56,12 +58,6 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 "
|
||||
#include "debug.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;
|
||||
AppManager * gAppManager;
|
||||
@@ -217,7 +213,7 @@ ServerApp::ArgvReceived(int32 argc, char **argv)
|
||||
|
||||
void
|
||||
ServerApp::StartAddonServer()
|
||||
{
|
||||
{
|
||||
// Try to launch media_addon_server by mime signature.
|
||||
// If it fails (for example on the Live CD, where the executable
|
||||
// hasn't yet been mimesetted), try from this application's
|
||||
@@ -225,7 +221,7 @@ ServerApp::StartAddonServer()
|
||||
status_t err = be_roster->Launch(B_MEDIA_ADDON_SERVER_SIGNATURE);
|
||||
if (err == B_OK)
|
||||
return;
|
||||
|
||||
|
||||
app_info info;
|
||||
BEntry entry;
|
||||
BDirectory dir;
|
||||
@@ -310,10 +306,10 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
ASSERT(request->delta == 1 || request->delta == -1);
|
||||
if (request->delta == 1) {
|
||||
rv = gNodeManager->IncrementAddonFlavorInstancesCount(
|
||||
request->addonid, request->flavorid, request->team);
|
||||
request->addon_id, request->flavor_id, request->team);
|
||||
} else {
|
||||
rv = gNodeManager->DecrementAddonFlavorInstancesCount(
|
||||
request->addonid, request->flavorid, request->team);
|
||||
request->addon_id, request->flavor_id, request->team);
|
||||
}
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
@@ -352,7 +348,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
= (server_get_mediaaddon_ref_request *)data;
|
||||
server_get_mediaaddon_ref_reply reply;
|
||||
entry_ref tempref;
|
||||
reply.result = gNodeManager->GetAddonRef(&tempref, msg->addonid);
|
||||
reply.result = gNodeManager->GetAddonRef(&tempref, msg->addon_id);
|
||||
reply.ref = tempref;
|
||||
write_port(msg->reply_port, 0, &reply, sizeof(reply));
|
||||
break;
|
||||
@@ -363,7 +359,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
const server_node_id_for_request *request
|
||||
= reinterpret_cast<const server_node_id_for_request *>(data);
|
||||
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));
|
||||
break;
|
||||
}
|
||||
@@ -432,7 +428,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
const server_get_node_for_request *request
|
||||
= reinterpret_cast<const server_get_node_for_request *>(data);
|
||||
server_get_node_for_reply reply;
|
||||
rv = gNodeManager->GetCloneForId(&reply.clone, request->nodeid,
|
||||
rv = gNodeManager->GetCloneForID(&reply.clone, request->node_id,
|
||||
request->team);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
@@ -453,7 +449,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
const server_register_node_request *request
|
||||
= reinterpret_cast<const server_register_node_request *>(data);
|
||||
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->port, request->team);
|
||||
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 *>(
|
||||
data);
|
||||
server_unregister_node_reply reply;
|
||||
rv = gNodeManager->UnregisterNode(&reply.addonid, &reply.flavorid,
|
||||
request->nodeid, request->team);
|
||||
rv = gNodeManager->UnregisterNode(&reply.addon_id, &reply.flavor_id,
|
||||
request->node_id, request->team);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
@@ -588,7 +584,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
server_register_mediaaddon_request *msg
|
||||
= (server_register_mediaaddon_request *)data;
|
||||
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));
|
||||
break;
|
||||
}
|
||||
@@ -597,20 +593,22 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
{
|
||||
server_unregister_mediaaddon_command *msg
|
||||
= (server_unregister_mediaaddon_command *)data;
|
||||
gNodeManager->UnregisterAddon(msg->addonid);
|
||||
gNodeManager->UnregisterAddon(msg->addon_id);
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_REGISTER_DORMANT_NODE:
|
||||
{
|
||||
xfer_server_register_dormant_node *msg
|
||||
= (xfer_server_register_dormant_node *)data;
|
||||
dormant_flavor_info dfi;
|
||||
xfer_server_register_dormant_node* msg
|
||||
= (xfer_server_register_dormant_node*)data;
|
||||
if (msg->purge_id > 0)
|
||||
gNodeManager->InvalidateDormantFlavorInfo(msg->purge_id);
|
||||
rv = dfi.Unflatten(msg->dfi_type, &(msg->dfi), msg->dfi_size);
|
||||
ASSERT(rv == B_OK);
|
||||
gNodeManager->AddDormantFlavorInfo(dfi);
|
||||
|
||||
dormant_flavor_info dormantFlavorInfo;
|
||||
status_t status = dormantFlavorInfo.Unflatten(msg->type,
|
||||
msg->flattened_data, msg->flattened_size);
|
||||
if (status == B_OK)
|
||||
gNodeManager->AddDormantFlavorInfo(dormantFlavorInfo);
|
||||
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 *)data;
|
||||
|
||||
xfer_server_get_dormant_nodes_reply reply;
|
||||
dormant_node_info * infos = new dormant_node_info[msg->maxcount];
|
||||
reply.count = msg->maxcount;
|
||||
reply.result = gNodeManager->GetDormantNodes(
|
||||
infos,
|
||||
&reply.count,
|
||||
msg->has_input ? &msg->inputformat : NULL,
|
||||
msg->has_output ? &msg->outputformat : NULL,
|
||||
msg->has_name ? msg->name : NULL,
|
||||
msg->require_kinds,
|
||||
msg->deny_kinds);
|
||||
reply.count = msg->max_count;
|
||||
|
||||
dormant_node_info* infos
|
||||
= new(std::nothrow) dormant_node_info[reply.count];
|
||||
if (infos != NULL) {
|
||||
reply.result = gNodeManager->GetDormantNodes(infos,
|
||||
&reply.count, msg->has_input ? &msg->input_format : NULL,
|
||||
msg->has_output ? &msg->output_format : NULL,
|
||||
msg->has_name ? msg->name : NULL, msg->require_kinds,
|
||||
msg->deny_kinds);
|
||||
} else
|
||||
reply.result = B_NO_MEMORY;
|
||||
|
||||
if (reply.result != B_OK)
|
||||
reply.count = 0;
|
||||
write_port(msg->reply_port, 0, &reply, sizeof(reply));
|
||||
if (reply.count > 0)
|
||||
write_port(msg->reply_port, 0, infos, reply.count
|
||||
* sizeof(dormant_node_info));
|
||||
delete [] infos;
|
||||
if (reply.count > 0) {
|
||||
write_port(msg->reply_port, 0, infos,
|
||||
reply.count * sizeof(dormant_node_info));
|
||||
}
|
||||
delete[] infos;
|
||||
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 *)data;
|
||||
dormant_flavor_info dfi;
|
||||
dormant_flavor_info dormantFlavorInfo;
|
||||
status_t rv;
|
||||
|
||||
rv = gNodeManager->GetDormantFlavorInfoFor(msg->addon,
|
||||
msg->flavor_id, &dfi);
|
||||
msg->flavor_id, &dormantFlavorInfo);
|
||||
if (rv != B_OK) {
|
||||
xfer_server_get_dormant_flavor_info_reply reply;
|
||||
reply.result = rv;
|
||||
write_port(msg->reply_port, 0, &reply, sizeof(reply));
|
||||
} else {
|
||||
xfer_server_get_dormant_flavor_info_reply *reply;
|
||||
int replysize;
|
||||
replysize = sizeof(xfer_server_get_dormant_flavor_info_reply)
|
||||
+ dfi.FlattenedSize();
|
||||
reply = (xfer_server_get_dormant_flavor_info_reply *)malloc(
|
||||
replysize);
|
||||
size_t replySize
|
||||
= sizeof(xfer_server_get_dormant_flavor_info_reply)
|
||||
+ dormantFlavorInfo.FlattenedSize();
|
||||
xfer_server_get_dormant_flavor_info_reply* reply
|
||||
= (xfer_server_get_dormant_flavor_info_reply*)malloc(
|
||||
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();
|
||||
reply->dfi_type = dfi.TypeCode();
|
||||
reply->result = dfi.Flatten(reply->dfi, reply->dfi_size);
|
||||
write_port(msg->reply_port, 0, reply, replysize);
|
||||
free(reply);
|
||||
write_port(msg->reply_port, 0, reply, replySize);
|
||||
free(reply);
|
||||
} else {
|
||||
xfer_server_get_dormant_flavor_info_reply reply;
|
||||
reply.result = B_NO_MEMORY;
|
||||
write_port(msg->reply_port, 0, &reply, sizeof(reply));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_SET_NODE_CREATOR:
|
||||
{
|
||||
const server_set_node_creator_request *request
|
||||
= reinterpret_cast<const server_set_node_creator_request *>(
|
||||
const server_set_node_creator_request* request
|
||||
= reinterpret_cast<const server_set_node_creator_request*>(
|
||||
data);
|
||||
server_set_node_creator_reply reply;
|
||||
rv = gNodeManager->SetNodeCreator(request->node, request->creator);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
status_t status = gNodeManager->SetNodeCreator(request->node,
|
||||
request->creator);
|
||||
request->SendReply(status, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -687,7 +698,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
const server_get_shared_buffer_area_request *>(data);
|
||||
server_get_shared_buffer_area_reply reply;
|
||||
|
||||
reply.area = gBufferManager->SharedBufferListID();
|
||||
reply.area = gBufferManager->SharedBufferListArea();
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
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 *>(data);
|
||||
|
||||
gBufferManager->UnregisterBuffer(cmd->team, cmd->bufferid);
|
||||
gBufferManager->UnregisterBuffer(cmd->team, cmd->buffer_id);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@ UsePrivateHeaders media shared ;
|
||||
|
||||
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 :
|
||||
main.cpp
|
||||
MediaFilePlayer.cpp
|
||||
|
||||
+461
-429
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user