changed media kit internal messaging and notification support

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1338 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2002-10-02 01:04:48 +00:00
parent 398e73f23b
commit f492510482
17 changed files with 639 additions and 545 deletions
+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _DATA_EXCHANGE_H
#define _DATA_EXCHANGE_H
#include <MediaDefs.h>
#include <MediaNode.h>
#include <MediaAddOn.h>
#include <Entry.h>
namespace BPrivate {
namespace media {
namespace dataexchange {
struct reply_data;
struct request_data;
// BMessage based data exchange with the media_server
status_t SendToServer(BMessage *msg);
status_t QueryServer(BMessage *request, BMessage *reply);
// BMessage based data exchange with the media_addon_server
status_t SendToAddonServer(BMessage *msg);
// Raw data based data exchange with the media_server
status_t SendToServer(int32 msgcode, void *msg, int size);
status_t QueryServer(int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize);
// Raw data based data exchange with the media_addon_server
status_t SendToAddonServer(int32 msgcode, void *msg, int size);
status_t QueryAddonServer(int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize);
// Raw data based data exchange with the media_server
status_t SendToPort(port_id sendport, int32 msgcode, void *msg, int size);
status_t QueryPort(port_id requestport, int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize);
// The base struct used for all raw requests
struct request_data
{
port_id reply_port;
void SendReply(reply_data *reply, int replysize) const;
};
// The base struct used for all raw replys
struct reply_data
{
status_t result;
};
}; // dataexchange
}; // media
}; // BPrivate
using namespace BPrivate::media::dataexchange;
enum {
// BMediaRoster notification service
MEDIA_SERVER_REQUEST_NOTIFICATIONS = 1000,
MEDIA_SERVER_CANCEL_NOTIFICATIONS,
MEDIA_SERVER_SEND_NOTIFICATIONS
};
struct request_addonserver_instantiate_dormant_node : public request_data
{
dormant_node_info info;
};
struct reply_addonserver_instantiate_dormant_node : public reply_data
{
media_node node;
};
#endif // _DATA_EXCHANGE_H
@@ -1,79 +0,0 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _NOTIFICATION_MANAGER_H
#define _NOTIFICATION_MANAGER_H
namespace BPrivate {
namespace media {
class NotificationManager
{
public:
enum notification_type_mask
{
notification_no_mask = 0,
notification_node_created = (1 << 0),
notification_node_deleted = (1 << 1),
notification_connection_made = (1 << 2),
notification_connection_broken = (1 << 3),
notification_buffer_created = (1 << 4),
notification_buffer_deleted = (1 << 5),
notification_transport_state = (1 << 6),
notification_parameter_changed = (1 << 7),
notification_format_change = (1 << 8),
notification_web_changed = (1 << 9),
notification_default_changed = (1 << 10),
notification_new_parameter_value= (1 << 11),
notification_node_stopped = (1 << 12),
notification_flavors_changed = (1 << 13),
notification_error = (1 << 31), // XXX, um well... always allow error notifications? Handled in the server
notification_basic = (notification_node_created | notification_node_deleted | notification_connection_made | notification_connection_broken),
notification_wildcard = (0xffffffff - notification_error) // exclude error, it is handled in the server
};
public:
NotificationManager();
~NotificationManager();
status_t Register(const BMessenger &notifyHandler, const media_node &node, notification_type_mask mask);
status_t Unregister(const BMessenger &notifyHandler, const media_node &node, notification_type_mask mask);
status_t ReportError(const media_node &node, BMediaNode::node_error what, const BMessage * info);
void NodesCreated(const media_node_id *ids, int32 count);
void NodesDeleted(const media_node_id *ids, int32 count);
void ConnectionMade(const media_input &input, const media_output &output, const media_format &format);
void ConnectionBroken(const media_source &source, const media_destination &destination);
void BuffersCreated(); // XXX fix
void BuffersDeleted(const media_buffer_id *ids, int32 count);
// XXX header file lists: B_MEDIA_TRANSPORT_STATE, /* "state", "location", "realtime" */
void FormatChanged(const media_source &source, const media_destination &destination, const media_format &format);
status_t ParameterChanged(const media_node &node, int32 parameterid);
void WebChanged(const media_node &node); // XXX fix
// XXX header file lists: B_MEDIA_DEFAULT_CHANGED /* "default", "node" -- handled by BMediaRoster */
status_t NewParameterValue(const media_node &node, int32 parameterid, bigtime_t when, const void *param, size_t paramsize);
void FlavorsChanged(media_addon_id addonis, int32 newcount, int32 gonecount);
void NodeStopped(const media_node &node, bigtime_t when); // XXX fix
static bool IsValidNotificationType(int32 notificationType);
static notification_type_mask NotificationType2Mask(int32 notificationType);
private:
status_t SendMessageToMediaServer(BMessage *msg);
private:
BMessenger *fMessenger;
};
}; // namespace media
}; // namespace BPrivate
#define NOTIFICATION_PARAM_WHAT "be:media:internal:what"
#define NOTIFICATION_PARAM_MASK "be:media:internal:mask"
extern BPrivate::media::NotificationManager *_NotificationManager;
#endif // _NOTIFICATION_MANAGER_H
+87
View File
@@ -0,0 +1,87 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _NOTIFICATIONS_H
#define _NOTIFICATIONS_H
namespace BPrivate {
namespace media {
namespace notifications {
/*
* This are the possible notifications that can be watched.
* 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()
*
* B_MEDIA_WILDCARD used to match any notification in Start/StopWatching
* B_MEDIA_NODE_CREATED "media_node_id" (multiple items)
* B_MEDIA_NODE_DELETED "media_node_id" (multiple items)
* B_MEDIA_CONNECTION_MADE "output", "input", "format"
* B_MEDIA_CONNECTION_BROKEN "source", "destination"
* B_MEDIA_BUFFER_CREATED "clone_info" -- handled by BMediaRoster
* B_MEDIA_BUFFER_DELETED "media_buffer_id" -- handled by BMediaRoster
* B_MEDIA_TRANSPORT_STATE "state", "location", "realtime"
* B_MEDIA_PARAMETER_CHANGED N "node", "parameter"
* B_MEDIA_FORMAT_CHANGED N "source", "destination", "format"
* B_MEDIA_WEB_CHANGED N "node"
* B_MEDIA_DEFAULT_CHANGED "default", "node" -- handled by BMediaRoster
* B_MEDIA_NEW_PARAMETER_VALUE N "node", "parameter", "when", "value"
* 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 &notifyHandler, const media_node &node, int32 notification);
// called by BMediaRoster::StopWatching()
status_t Unregister(const BMessenger &notifyHandler, const media_node &node, int32 notification);
// called by BMediaNode::ReportError()
status_t ReportError(const media_node &node, BMediaNode::node_error what, const BMessage * info);
void NodesCreated(const media_node_id *ids, int32 count);
void NodesDeleted(const media_node_id *ids, int32 count);
void ConnectionMade(const media_input &input, const media_output &output, const media_format &format);
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
// handled. NOT CALLED by BMediaAddOn::NotifyFlavorChange()
void FlavorsChanged(media_addon_id addonid, int32 newcount, int32 gonecount);
void FormatChanged(const media_source &source, const media_destination &destination, const media_format &format);
// XXX missing: B_MEDIA_TRANSPORT_STATE /* "state", "location", "realtime" */
// XXX missing: B_MEDIA_DEFAULT_CHANGED /* "default", "node" */
}; // namespace notifications
}; // namespace media
}; // namespace BPrivate
#define NOTIFICATION_PARAM_WHAT "be:media:internal:what"
#define NOTIFICATION_PARAM_TEAM "be:media:internal:team"
#define NOTIFICATION_PARAM_MESSENGER "be:media:internal:messenger"
#endif // _NOTIFICATIONS_H
+3 -3
View File
@@ -177,7 +177,7 @@ BBuffer::BBuffer(const buffer_clone_info & info) :
BMessage request(MEDIA_SERVER_GET_SHARED_BUFFER_AREA); BMessage request(MEDIA_SERVER_GET_SHARED_BUFFER_AREA);
BMessage reply; BMessage reply;
if (MediaKitPrivate::QueryServer(&request, &reply) != B_OK) if (QueryServer(&request, &reply) != B_OK)
return; return;
id = reply.FindInt32("area"); id = reply.FindInt32("area");
@@ -204,7 +204,7 @@ BBuffer::BBuffer(const buffer_clone_info & info) :
// until the last buffer has been unregistered // until the last buffer has been unregistered
// the area_id of the cached area is passed back to us, and we clone it. // the area_id of the cached area is passed back to us, and we clone it.
if (MediaKitPrivate::QueryServer(&create, &response) != B_OK) if (QueryServer(&create, &response) != B_OK)
return; return;
// the response from media server contains enough information // the response from media server contains enough information
@@ -245,7 +245,7 @@ BBuffer::~BBuffer()
// when the last clone of this buffer is gone, // when the last clone of this buffer is gone,
// media_server will also remove it's cached area // media_server will also remove it's cached area
MediaKitPrivate::QueryServer(&unregister, &response); QueryServer(&unregister, &response);
delete_area(fArea); delete_area(fArea);
} }
+1 -1
View File
@@ -37,7 +37,7 @@ BBufferGroup::InitBufferGroup()
BMessage request(MEDIA_SERVER_GET_SHARED_BUFFER_AREA); BMessage request(MEDIA_SERVER_GET_SHARED_BUFFER_AREA);
BMessage reply; BMessage reply;
fInitError = MediaKitPrivate::QueryServer(&request, &reply); fInitError = QueryServer(&request, &reply);
if (fInitError != B_OK) if (fInitError != B_OK)
return fInitError; return fInitError;
+5 -3
View File
@@ -5,7 +5,7 @@
***********************************************************************/ ***********************************************************************/
#include <Controllable.h> #include <Controllable.h>
#include "debug.h" #include "debug.h"
#include "NotificationManager.h" #include "Notifications.h"
/************************************************************* /*************************************************************
* protected BControllable * protected BControllable
@@ -60,6 +60,8 @@ status_t
BControllable::SetParameterWeb(BParameterWeb *web) BControllable::SetParameterWeb(BParameterWeb *web)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
BPrivate::media::notifications::WebChanged(Node());
return B_ERROR; return B_ERROR;
} }
@@ -80,7 +82,7 @@ status_t
BControllable::BroadcastChangedParameter(int32 id) BControllable::BroadcastChangedParameter(int32 id)
{ {
CALLED(); CALLED();
return _NotificationManager->ParameterChanged(Node(), id); return BPrivate::media::notifications::ParameterChanged(Node(), id);
} }
@@ -91,7 +93,7 @@ BControllable::BroadcastNewParameterValue(bigtime_t when,
size_t valueSize) size_t valueSize)
{ {
CALLED(); CALLED();
return _NotificationManager->NewParameterValue(Node(), id, when, newValue, valueSize); return BPrivate::media::notifications::NewParameterValue(Node(), id, when, newValue, valueSize);
} }
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <OS.h>
#include "DataExchange.h"
namespace BPrivate {
namespace media {
team_id team;
namespace dataexchange {
void
request_data::SendReply(reply_data *reply, int replysize) const
{
}
// BMessage based data exchange with the media_server
status_t SendToServer(BMessage *msg)
{
return B_OK;
}
status_t QueryServer(BMessage *request, BMessage *reply)
{
return B_OK;
}
// BMessage based data exchange with the media_addon_server
status_t SendToAddonServer(BMessage *msg)
{
return B_OK;
}
// Raw data based data exchange with the media_server
status_t SendToServer(int32 msgcode, void *msg, int size)
{
return B_OK;
}
status_t QueryServer(int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize)
{
return B_OK;
}
// Raw data based data exchange with the media_addon_server
status_t SendToAddonServer(int32 msgcode, void *msg, int size)
{
return B_OK;
}
status_t QueryAddonServer(int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize)
{
return B_OK;
}
// Raw data based data exchange with the media_server
status_t SendToPort(port_id sendport, int32 msgcode, void *msg, int size)
{
return B_OK;
}
status_t QueryPort(port_id requestport, int32 msgcode, const request_data *request, int requestsize, reply_data *reply, int replysize)
{
return B_OK;
}
}; // dataexchange
}; // media
}; // BPrivate
+2 -1
View File
@@ -42,9 +42,10 @@ SharedLibrary media :
TimeSource.cpp TimeSource.cpp
# Internal Functionality # Internal Functionality
DataExchange.cpp
PortPool.cpp PortPool.cpp
DormantNodeManager.cpp DormantNodeManager.cpp
NotificationManager.cpp Notifications.cpp
SystemTimeSource.cpp SystemTimeSource.cpp
BufferIdCache.cpp BufferIdCache.cpp
SharedBufferList.cpp SharedBufferList.cpp
+20 -3
View File
@@ -14,7 +14,7 @@
#include "SystemTimeSource.h" #include "SystemTimeSource.h"
#include "debug.h" #include "debug.h"
#include "ServerInterface.h" #include "ServerInterface.h"
#include "NotificationManager.h" #include "Notifications.h"
// don't rename this one, it's used and exported for binary compatibility // don't rename this one, it's used and exported for binary compatibility
int32 BMediaNode::_m_changeTag = 0; int32 BMediaNode::_m_changeTag = 0;
@@ -214,9 +214,26 @@ BMediaNode::ReportError(node_error what,
const BMessage *info) const BMessage *info)
{ {
CALLED(); CALLED();
// sanity check the what value
switch (what) {
case BMediaNode::B_NODE_FAILED_START:
case BMediaNode::B_NODE_FAILED_STOP:
case BMediaNode::B_NODE_FAILED_SEEK:
case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
case BMediaNode::B_NODE_FAILED_TIME_WARP:
case BMediaNode::B_NODE_FAILED_PREROLL:
case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
case BMediaNode::B_NODE_IN_DISTRESS:
break;
default:
TRACE("BMediaNode::ReportError: invalid what!\n");
return B_BAD_VALUE;
}
// Transmits the error code specified by what to anyone // Transmits the error code specified by what to anyone
// that's receiving notifications from this node // that's receiving notifications from this node
return _NotificationManager->ReportError(Node(), what, info); return BPrivate::media::notifications::ReportError(Node(), what, info);
} }
@@ -228,7 +245,7 @@ BMediaNode::NodeStopped(bigtime_t whenPerformance)
// finished handling a stop request. // finished handling a stop request.
// notify anyone who is listening for stop notifications! // notify anyone who is listening for stop notifications!
_NotificationManager->NodeStopped(Node(), whenPerformance); BPrivate::media::notifications::NodeStopped(Node(), whenPerformance);
// XXX If your node is a BBufferProducer, downstream consumers // XXX If your node is a BBufferProducer, downstream consumers
// XXX will be notified that your node stopped (automatically, no less) // XXX will be notified that your node stopped (automatically, no less)
+29 -75
View File
@@ -16,11 +16,15 @@
#include "debug.h" #include "debug.h"
#include "PortPool.h" #include "PortPool.h"
#include "ServerInterface.h" #include "ServerInterface.h"
#include "DataExchange.h"
#include "DormantNodeManager.h" #include "DormantNodeManager.h"
#include "NotificationManager.h" #include "Notifications.h"
static BMessenger *ServerMessenger = 0; using namespace BPrivate::media;
static team_id team;
namespace BPrivate { namespace media {
extern team_id team;
}; };
// the BMediaRoster destructor is private, // the BMediaRoster destructor is private,
// but _DefaultDeleter is a friend class of // but _DefaultDeleter is a friend class of
@@ -31,48 +35,15 @@ public:
void Delete() { delete BMediaRoster::_sDefault; } void Delete() { delete BMediaRoster::_sDefault; }
}; };
_DefaultDeleter _deleter;
namespace MediaKitPrivate namespace MediaKitPrivate
{ {
class RosterSingleton
{
public:
RosterSingleton()
{
thread_info info;
get_thread_info(find_thread(NULL), &info);
team = info.team;
ServerMessenger = new BMessenger(NEW_MEDIA_SERVER_SIGNATURE);
}
~RosterSingleton()
{
_DefaultDeleter deleter;
deleter.Delete(); // deletes BMediaRoster::_sDefault
delete ServerMessenger;
}
};
RosterSingleton singleton;
status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id = NULL, BString * out_input_name = NULL); status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id = NULL, BString * out_input_name = NULL);
status_t SetNode(node_type type, const media_node *node, const dormant_node_info *info = NULL, const media_input *input = NULL); status_t SetNode(node_type type, const media_node *node, const dormant_node_info *info = NULL, const media_input *input = NULL);
status_t QueryServer(BMessage *query, BMessage *reply)
{
status_t status;
status = ServerMessenger->SendMessage(query,reply);
if (status != B_OK || reply->what != B_OK) {
TRACE("QueryServer failed! status = 0x%08lx\n",status);
TRACE("Query:\n");
query->PrintToStream();
TRACE("Reply:\n");
reply->PrintToStream();
}
return status;
}
status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id, BString * out_input_name) status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id, BString * out_input_name)
{ {
if (out_node == NULL) if (out_node == NULL)
@@ -154,7 +125,7 @@ BMediaRoster::GetVideoInput(media_node * out_node)
return MediaKitPrivate::GetNode(VIDEO_INPUT, out_node); return MediaKitPrivate::GetNode(VIDEO_INPUT, out_node);
} }
status_t status_t
BMediaRoster::GetAudioInput(media_node * out_node) BMediaRoster::GetAudioInput(media_node * out_node)
{ {
@@ -837,8 +808,7 @@ BMediaRoster::StartWatching(const BMessenger & where)
TRACE("BMediaRoster::StartWatching: messenger invalid!\n"); TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
return B_BAD_VALUE; return B_BAD_VALUE;
} }
return _NotificationManager->Register(where, media_node::null, return BPrivate::media::notifications::Register(where, media_node::null, B_MEDIA_WILDCARD);
BPrivate::media::NotificationManager::notification_basic);
} }
@@ -851,12 +821,11 @@ BMediaRoster::StartWatching(const BMessenger & where,
TRACE("BMediaRoster::StartWatching: messenger invalid!\n"); TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
return B_BAD_VALUE; return B_BAD_VALUE;
} }
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) { if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) {
TRACE("BMediaRoster::StartWatching: notificationType invalid!\n"); TRACE("BMediaRoster::StartWatching: notificationType invalid!\n");
return B_BAD_VALUE; return B_BAD_VALUE;
} }
return _NotificationManager->Register(where, media_node::null, return BPrivate::media::notifications::Register(where, media_node::null, notificationType);
BPrivate::media::NotificationManager::NotificationType2Mask(notificationType));
} }
@@ -874,12 +843,11 @@ BMediaRoster::StartWatching(const BMessenger & where,
TRACE("BMediaRoster::StartWatching: node invalid!\n"); TRACE("BMediaRoster::StartWatching: node invalid!\n");
return B_MEDIA_BAD_NODE; return B_MEDIA_BAD_NODE;
} }
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) { if (false == BPrivate::media::notifications::IsValidNotificationRequest(true, notificationType)) {
TRACE("BMediaRoster::StartWatching: notificationType invalid!\n"); TRACE("BMediaRoster::StartWatching: notificationType invalid!\n");
return B_BAD_VALUE; return B_BAD_VALUE;
} }
return _NotificationManager->Register(where, node, return BPrivate::media::notifications::Register(where, node, notificationType);
BPrivate::media::NotificationManager::NotificationType2Mask(notificationType));
} }
@@ -888,8 +856,7 @@ BMediaRoster::StopWatching(const BMessenger & where)
{ {
CALLED(); CALLED();
// messenger may already be invalid, so we don't check this // messenger may already be invalid, so we don't check this
return _NotificationManager->Unregister(where, media_node::null, return BPrivate::media::notifications::Unregister(where, media_node::null, B_MEDIA_WILDCARD);
BPrivate::media::NotificationManager::notification_basic);
} }
@@ -899,12 +866,11 @@ BMediaRoster::StopWatching(const BMessenger & where,
{ {
CALLED(); CALLED();
// messenger may already be invalid, so we don't check this // messenger may already be invalid, so we don't check this
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) { if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) {
TRACE("BMediaRoster::StopWatching: notificationType invalid!\n"); TRACE("BMediaRoster::StopWatching: notificationType invalid!\n");
return B_BAD_VALUE; return B_BAD_VALUE;
} }
return _NotificationManager->Unregister(where, media_node::null, return BPrivate::media::notifications::Unregister(where, media_node::null, notificationType);
BPrivate::media::NotificationManager::NotificationType2Mask(notificationType));
} }
@@ -919,12 +885,11 @@ BMediaRoster::StopWatching(const BMessenger & where,
TRACE("BMediaRoster::StopWatching: node invalid!\n"); TRACE("BMediaRoster::StopWatching: node invalid!\n");
return B_MEDIA_BAD_NODE; return B_MEDIA_BAD_NODE;
} }
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) { if (false == BPrivate::media::notifications::IsValidNotificationRequest(true, notificationType)) {
TRACE("BMediaRoster::StopWatching: notificationType invalid!\n"); TRACE("BMediaRoster::StopWatching: notificationType invalid!\n");
return B_BAD_VALUE; return B_BAD_VALUE;
} }
return _NotificationManager->Unregister(where, node, return BPrivate::media::notifications::Unregister(where, node, notificationType);
BPrivate::media::NotificationManager::NotificationType2Mask(notificationType));
} }
@@ -1106,27 +1071,16 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info,
// forward this request into the media_addon_server, // forward this request into the media_addon_server,
// which in turn will call InstantiateDormantNode() // which in turn will call InstantiateDormantNode()
// to create it there localy // to create it there localy
xfer_addonserver_instantiate_dormant_node msg; request_addonserver_instantiate_dormant_node request;
xfer_addonserver_instantiate_dormant_node_reply reply; reply_addonserver_instantiate_dormant_node reply;
port_id port;
status_t rv; status_t rv;
int32 code;
port = find_port("media_addon_server port"); request.info = in_info;
if (port <= B_OK) rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request, sizeof(request), &reply, sizeof(reply));
return B_ERROR; if (rv == B_OK) {
msg.info = in_info; *out_node = reply.node;
msg.reply_port = _PortPool->GetPort();
rv = write_port(port, ADDONSERVER_INSTANTIATE_DORMANT_NODE, &msg, sizeof(msg));
if (rv != B_OK) {
_PortPool->PutPort(msg.reply_port);
return rv;
} }
rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); return rv;
_PortPool->PutPort(msg.reply_port);
if (rv < B_OK)
return rv;
*out_node = reply.node;
return reply.result;
} }
// XXX SOMETHING IS VERY WRONG HERE // XXX SOMETHING IS VERY WRONG HERE
@@ -1492,7 +1446,7 @@ BMediaRoster::~BMediaRoster()
BMessage msg(MEDIA_SERVER_UNREGISTER_APP); BMessage msg(MEDIA_SERVER_UNREGISTER_APP);
BMessage reply; BMessage reply;
msg.AddInt32("team",team); msg.AddInt32("team",team);
ServerMessenger->SendMessage(&msg,&reply); QueryServer(&msg, &reply);
} }
@@ -1529,7 +1483,7 @@ BMediaRoster::BMediaRoster() :
BMessage msg(MEDIA_SERVER_REGISTER_APP); BMessage msg(MEDIA_SERVER_REGISTER_APP);
BMessage reply; BMessage reply;
msg.AddInt32("team",team); msg.AddInt32("team",team);
ServerMessenger->SendMessage(&msg,&reply); QueryServer(&msg,&reply);
} }
/* static */ status_t /* static */ status_t
-336
View File
@@ -1,336 +0,0 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
/* 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.
*/
#include <Messenger.h>
#include <MediaNode.h>
#include "debug.h"
#include "PortPool.h"
#include "ServerInterface.h"
#include "NotificationManager.h"
static BPrivate::media::NotificationManager manager;
BPrivate::media::NotificationManager *_NotificationManager = &manager;
namespace BPrivate {
namespace media {
NotificationManager::NotificationManager()
: fMessenger(new BMessenger())
{
CALLED();
}
NotificationManager::~NotificationManager()
{
CALLED();
delete fMessenger;
}
status_t
NotificationManager::Register(const BMessenger &notifyHandler, const media_node &node, notification_type_mask mask)
{
CALLED();
BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS);
return SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::Unregister(const BMessenger &notifyHandler, const media_node &node, notification_type_mask mask)
{
CALLED();
BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS);
return SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::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();
// sanity check the what value
switch (what) {
case BMediaNode::B_NODE_FAILED_START:
case BMediaNode::B_NODE_FAILED_STOP:
case BMediaNode::B_NODE_FAILED_SEEK:
case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
case BMediaNode::B_NODE_FAILED_TIME_WARP:
case BMediaNode::B_NODE_FAILED_PREROLL:
case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
case BMediaNode::B_NODE_IN_DISTRESS:
break;
default:
TRACE("BMediaNode::ReportError (NotificationManager::ReportError): invalid what!\n");
return B_BAD_VALUE;
}
BMessage msg;
if (info)
msg = *info;
msg.what = MEDIA_SERVER_SEND_NOTIFICATIONS;
msg.AddInt32(NOTIFICATION_PARAM_WHAT, what);
msg.AddInt32(NOTIFICATION_PARAM_MASK, notification_error);
return SendMessageToMediaServer(&msg);
}
void
NotificationManager::NodesCreated(const media_node_id *ids, int32 count)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_CREATED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_NODE_CREATED));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::NodesDeleted(const media_node_id *ids, int32 count)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_DELETED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_NODE_DELETED));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::ConnectionMade(const media_input &input, const media_output &output, const media_format &format)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_MADE);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_CONNECTION_MADE));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::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.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_CONNECTION_BROKEN));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::BuffersCreated() // XXX fix
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_BUFFER_CREATED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_BUFFER_CREATED));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::BuffersDeleted(const media_buffer_id *ids, int32 count)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_BUFFER_DELETED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_BUFFER_DELETED));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::FormatChanged(const media_source &source, const media_destination &destination, const media_format &format)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FORMAT_CHANGED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_FORMAT_CHANGED));
SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::ParameterChanged(const media_node &node, int32 parameterid)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_PARAMETER_CHANGED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_PARAMETER_CHANGED));
return SendMessageToMediaServer(&msg);
}
void
NotificationManager::WebChanged(const media_node &node) // XXX fix
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_WEB_CHANGED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_WEB_CHANGED));
SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::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.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_NEW_PARAMETER_VALUE));
return SendMessageToMediaServer(&msg);
}
void
NotificationManager::FlavorsChanged(media_addon_id addonis, int32 newcount, int32 gonecount)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FLAVORS_CHANGED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_FLAVORS_CHANGED));
SendMessageToMediaServer(&msg);
}
void
NotificationManager::NodeStopped(const media_node &node, bigtime_t when) // XXX fix
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_STOPPED);
msg.AddInt32(NOTIFICATION_PARAM_MASK, NotificationType2Mask(B_MEDIA_NODE_STOPPED));
SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::SendMessageToMediaServer(BMessage *msg)
{
#define TIMEOUT 100000
BMessage reply;
status_t rv;
if (!fMessenger->IsValid()) {
TRACE("NotificationManager::SendMessageToMediaServer: setting new messenger target\n");
*fMessenger = BMessenger(NEW_MEDIA_SERVER_SIGNATURE);
}
rv = fMessenger->SendMessage(msg, &reply, TIMEOUT);
if (rv != B_OK) {
TRACE("NotificationManager::SendMessageToMediaServer: failed to send message\n");
} else {
rv = reply.what;
}
return rv;
}
bool
NotificationManager::IsValidNotificationType(int32 notificationType)
{
switch (notificationType) {
case BMediaNode::B_NODE_FAILED_START:
case BMediaNode::B_NODE_FAILED_STOP:
case BMediaNode::B_NODE_FAILED_SEEK:
case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
case BMediaNode::B_NODE_FAILED_TIME_WARP:
case BMediaNode::B_NODE_FAILED_PREROLL:
case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
case BMediaNode::B_NODE_IN_DISTRESS:
debugger("NotificationManager::IsValidNotificationType, encountered BMediaNode Error otification\n");
return false; // XXX we consider registering for this notifications as impossible, you always get them anyway
case B_MEDIA_WILDCARD:
case B_MEDIA_NODE_CREATED:
case B_MEDIA_NODE_DELETED:
case B_MEDIA_CONNECTION_MADE:
case B_MEDIA_CONNECTION_BROKEN:
case B_MEDIA_BUFFER_CREATED:
case B_MEDIA_BUFFER_DELETED:
case B_MEDIA_TRANSPORT_STATE:
case B_MEDIA_PARAMETER_CHANGED:
case B_MEDIA_FORMAT_CHANGED:
case B_MEDIA_WEB_CHANGED:
case B_MEDIA_DEFAULT_CHANGED:
case B_MEDIA_NEW_PARAMETER_VALUE:
case B_MEDIA_NODE_STOPPED:
case B_MEDIA_FLAVORS_CHANGED:
return true;
default:
return false;
}
}
NotificationManager::notification_type_mask
NotificationManager::NotificationType2Mask(int32 notificationType)
{
switch (notificationType) {
case BMediaNode::B_NODE_FAILED_START:
case BMediaNode::B_NODE_FAILED_STOP:
case BMediaNode::B_NODE_FAILED_SEEK:
case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
case BMediaNode::B_NODE_FAILED_TIME_WARP:
case BMediaNode::B_NODE_FAILED_PREROLL:
case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
case BMediaNode::B_NODE_IN_DISTRESS:
return notification_error;
case B_MEDIA_WILDCARD:
return notification_wildcard;
case B_MEDIA_NODE_CREATED:
return notification_node_created;
case B_MEDIA_NODE_DELETED:
return notification_node_deleted;
case B_MEDIA_CONNECTION_MADE:
return notification_connection_made;
case B_MEDIA_CONNECTION_BROKEN:
return notification_connection_broken;
case B_MEDIA_BUFFER_CREATED:
return notification_buffer_created;
case B_MEDIA_BUFFER_DELETED:
return notification_buffer_deleted;
case B_MEDIA_TRANSPORT_STATE:
return notification_transport_state;
case B_MEDIA_PARAMETER_CHANGED:
return notification_parameter_changed;
case B_MEDIA_FORMAT_CHANGED:
return notification_format_change;
case B_MEDIA_WEB_CHANGED:
return notification_web_changed;
case B_MEDIA_DEFAULT_CHANGED:
return notification_default_changed;
case B_MEDIA_NEW_PARAMETER_VALUE:
return notification_new_parameter_value;
case B_MEDIA_NODE_STOPPED:
return notification_node_stopped;
case B_MEDIA_FLAVORS_CHANGED:
return notification_flavors_changed;
default:
return notification_no_mask;
}
}
}; // namespace media
}; // namespace BPrivate
+261
View File
@@ -0,0 +1,261 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
/* 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.
*/
#include <Messenger.h>
#include <MediaNode.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 &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.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 &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.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
return BPrivate::media::dataexchange::SendToServer(&msg);
}
status_t
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)
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)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_CREATED);
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)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_DELETED);
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)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_MADE);
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)
{
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)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_BUFFER_CREATED);
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)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_BUFFER_DELETED);
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)
{
CALLED();
BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FORMAT_CHANGED);
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)
{
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);
return BPrivate::media::dataexchange::SendToServer(&msg);
}
void
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)
{
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.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)
{
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);
BPrivate::media::dataexchange::SendToServer(&msg);
}
void
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" */
bool
IsValidNotificationRequest(bool node_specific, int32 notification)
{
switch (notification) {
// valid for normal and node specific watching
case B_MEDIA_WILDCARD:
case B_MEDIA_NODE_CREATED:
case B_MEDIA_NODE_DELETED:
case B_MEDIA_CONNECTION_MADE:
case B_MEDIA_CONNECTION_BROKEN:
case B_MEDIA_BUFFER_CREATED:
case B_MEDIA_BUFFER_DELETED:
case B_MEDIA_TRANSPORT_STATE:
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:
case B_MEDIA_WEB_CHANGED:
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
+12
View File
@@ -22,6 +22,18 @@ NodeManager::~NodeManager()
delete fAddonPathMap; delete fAddonPathMap;
} }
/* Add media_node_id of all live nodes to the message
* int32 "media_node_id" (multiple items)
*/
status_t
NodeManager::GetLiveNodes(BMessage *msg)
{
msg->AddInt32("media_node_id", 1);
msg->AddInt32("media_node_id", 2);
msg->AddInt32("media_node_id", 3);
return B_OK;
}
void void
NodeManager::RegisterAddon(const entry_ref &ref, media_addon_id *newid) NodeManager::RegisterAddon(const entry_ref &ref, media_addon_id *newid)
{ {
+5
View File
@@ -26,6 +26,11 @@ public:
status_t LoadState(); status_t LoadState();
status_t SaveState(); status_t SaveState();
/* Add media_node_id of all live nodes to the message
* int32 "media_node_id" (multiple items)
*/
status_t GetLiveNodes(BMessage *msg);
void AddDormantFlavorInfo(const dormant_flavor_info &dfi); void AddDormantFlavorInfo(const dormant_flavor_info &dfi);
void RemoveDormantFlavorInfo(media_addon_id id); void RemoveDormantFlavorInfo(media_addon_id id);
void RegisterAddon(const entry_ref &ref, media_addon_id *newid); void RegisterAddon(const entry_ref &ref, media_addon_id *newid);
+4 -21
View File
@@ -18,11 +18,6 @@ enum {
MEDIA_SERVER_REGISTER_BUFFER, MEDIA_SERVER_REGISTER_BUFFER,
MEDIA_SERVER_UNREGISTER_BUFFER, MEDIA_SERVER_UNREGISTER_BUFFER,
// BMediaRoster notification service
MEDIA_SERVER_REQUEST_NOTIFICATIONS,
MEDIA_SERVER_CANCEL_NOTIFICATIONS,
MEDIA_SERVER_SEND_NOTIFICATIONS,
// Something else // Something else
MEDIA_SERVER_SET_VOLUME, MEDIA_SERVER_SET_VOLUME,
MEDIA_SERVER_GET_VOLUME, MEDIA_SERVER_GET_VOLUME,
@@ -588,22 +583,10 @@ struct xfer_consumer_seek_tag_requested_reply
status_t result; status_t result;
}; };
struct xfer_addonserver_instantiate_dormant_node namespace BPrivate { namespace media { namespace dataexchange {
{
dormant_node_info info;
port_id reply_port;
};
struct xfer_addonserver_instantiate_dormant_node_reply
{
media_node node;
status_t result;
};
// implementation contained in libmedia.so (MediaRoster.cpp)
namespace MediaKitPrivate
{
status_t QueryServer(BMessage *query, BMessage *reply); status_t QueryServer(BMessage *query, BMessage *reply);
}; }; }; };
using namespace BPrivate::media::dataexchange;
#endif #endif
+4 -3
View File
@@ -6,6 +6,7 @@
#include <Autolock.h> #include <Autolock.h>
#include "NotificationProcessor.h" #include "NotificationProcessor.h"
#include "ServerInterface.h" #include "ServerInterface.h"
#include "DataExchange.h"
#include "BufferManager.h" #include "BufferManager.h"
#include "NodeManager.h" #include "NodeManager.h"
#include "AppManager.h" #include "AppManager.h"
@@ -547,9 +548,9 @@ void ServerApp::MessageReceived(BMessage *msg)
case MEDIA_SERVER_GET_SHARED_BUFFER_AREA: GetSharedBufferArea(msg); break; case MEDIA_SERVER_GET_SHARED_BUFFER_AREA: GetSharedBufferArea(msg); break;
case MEDIA_SERVER_REGISTER_BUFFER: RegisterBuffer(msg); break; case MEDIA_SERVER_REGISTER_BUFFER: RegisterBuffer(msg); break;
case MEDIA_SERVER_UNREGISTER_BUFFER: UnregisterBuffer(msg); break; case MEDIA_SERVER_UNREGISTER_BUFFER: UnregisterBuffer(msg); break;
case MEDIA_SERVER_REQUEST_NOTIFICATIONS: fNotificationProcessor->RequestNotifications(msg); break; case MEDIA_SERVER_REQUEST_NOTIFICATIONS: fNotificationProcessor->EnqueueMessage(msg); break;
case MEDIA_SERVER_CANCEL_NOTIFICATIONS: fNotificationProcessor->CancelNotifications(msg); break; case MEDIA_SERVER_CANCEL_NOTIFICATIONS: fNotificationProcessor->EnqueueMessage(msg); break;
case MEDIA_SERVER_SEND_NOTIFICATIONS: fNotificationProcessor->SendNotifications(msg); break; case MEDIA_SERVER_SEND_NOTIFICATIONS: fNotificationProcessor->EnqueueMessage(msg); break;
case MEDIA_SERVER_GET_NODE_ID: GetNodeID(msg); break; case MEDIA_SERVER_GET_NODE_ID: GetNodeID(msg); break;
+43 -20
View File
@@ -15,9 +15,11 @@
#include "debug.h" #include "debug.h"
#include "TMap.h" #include "TMap.h"
#include "ServerInterface.h" #include "ServerInterface.h"
#include "DataExchange.h"
#include "DormantNodeManager.h" #include "DormantNodeManager.h"
#include "Notifications.h"
#define USER_ADDON_PATH "/boot/home/Develop/OpenBeOS/current/distro/x86.R1/beos/system/add-ons/media" #define USER_ADDON_PATH "../add-ons/media"
void DumpFlavorInfo(const flavor_info *info); void DumpFlavorInfo(const flavor_info *info);
@@ -37,7 +39,8 @@ public:
void ScanAddOnFlavors(BMediaAddOn *addon); void ScanAddOnFlavors(BMediaAddOn *addon);
Map<ino_t,media_addon_id> *filemap; Map<ino_t, media_addon_id> *filemap;
Map<media_addon_id, int32> *flavorcountmap;
BMediaRoster *mediaroster; BMediaRoster *mediaroster;
ino_t DirNodeSystem; ino_t DirNodeSystem;
@@ -50,7 +53,8 @@ MediaAddonServer::MediaAddonServer(const char *sig) :
BApplication(sig) BApplication(sig)
{ {
mediaroster = BMediaRoster::Roster(); mediaroster = BMediaRoster::Roster();
filemap = new Map<ino_t,media_addon_id>; filemap = new Map<ino_t, media_addon_id>;
flavorcountmap = new Map<media_addon_id, int32>;
control_port = create_port(64,"media_addon_server port"); control_port = create_port(64,"media_addon_server port");
control_thread = spawn_thread(controlthread,"media_addon_server control",12,this); control_thread = spawn_thread(controlthread,"media_addon_server control",12,this);
resume_thread(control_thread); resume_thread(control_thread);
@@ -68,6 +72,7 @@ MediaAddonServer::~MediaAddonServer()
_DormantNodeManager->UnregisterAddon(id); _DormantNodeManager->UnregisterAddon(id);
delete filemap; delete filemap;
delete flavorcountmap;
} }
void void
@@ -76,10 +81,10 @@ MediaAddonServer::HandleMessage(int32 code, void *data, size_t size)
switch (code) { switch (code) {
case ADDONSERVER_INSTANTIATE_DORMANT_NODE: case ADDONSERVER_INSTANTIATE_DORMANT_NODE:
{ {
const xfer_addonserver_instantiate_dormant_node *msg = (const xfer_addonserver_instantiate_dormant_node *)data; const request_addonserver_instantiate_dormant_node *msg = (const request_addonserver_instantiate_dormant_node *)data;
xfer_addonserver_instantiate_dormant_node_reply reply; reply_addonserver_instantiate_dormant_node reply;
reply.result = mediaroster->InstantiateDormantNode(msg->info, &reply.node); reply.result = mediaroster->InstantiateDormantNode(msg->info, &reply.node);
write_port(msg->reply_port, 0, &reply, sizeof(reply)); msg->SendReply(&reply, sizeof(reply));
break; break;
} }
@@ -140,10 +145,13 @@ MediaAddonServer::ReadyToRun()
void void
MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon) MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon)
{ {
int flavorcount; int32 *flavorcount;
media_addon_id purge_id; int32 oldflavorcount;
int32 newflavorcount;
media_addon_id addon_id;
port_id port; port_id port;
status_t rv; status_t rv;
bool b;
ASSERT(addon); ASSERT(addon);
ASSERT(addon->AddonID() > 0); ASSERT(addon->AddonID() > 0);
@@ -156,13 +164,21 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon)
return; return;
} }
// the server should remove previously registered "dormant_flavor_info"s // cache the media_addon_id in a local variable to avoid
purge_id = addon->AddonID(); // calling BMediaAddOn::AddonID() too often
addon_id = addon->AddonID();
// update the cached flavor count, get oldflavorcount and newflavorcount
b = flavorcountmap->GetPointer(addon->AddonID(), &flavorcount);
ASSERT(b);
oldflavorcount = *flavorcount;
newflavorcount = addon->CountFlavors();
*flavorcount = newflavorcount;
printf("%d old flavors, %d new flavors\n", oldflavorcount, newflavorcount);
flavorcount = addon->CountFlavors(); // during the first update (i == 0), the server removes old dormant_flavor_infos
printf("%d flavors:\n",flavorcount); for (int i = 0; i < newflavorcount; i++) {
for (int i = 0; i < flavorcount; i++) {
const flavor_info *info; const flavor_info *info;
printf("flavor %d:\n",i); printf("flavor %d:\n",i);
if (B_OK != addon->GetFlavorAt(i, &info)) { if (B_OK != addon->GetFlavorAt(i, &info)) {
@@ -174,7 +190,7 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon)
dormant_flavor_info dfi; dormant_flavor_info dfi;
dfi = *info; dfi = *info;
dfi.node_info.addon = addon->AddonID(); dfi.node_info.addon = addon_id;
dfi.node_info.flavor_id = info->internal_id; dfi.node_info.flavor_id = info->internal_id;
strncpy(dfi.node_info.name, info->name, B_MEDIA_NAME_LENGTH - 1); strncpy(dfi.node_info.name, info->name, B_MEDIA_NAME_LENGTH - 1);
dfi.node_info.name[B_MEDIA_NAME_LENGTH - 1] = 0; dfi.node_info.name[B_MEDIA_NAME_LENGTH - 1] = 0;
@@ -187,7 +203,11 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon)
msgsize = flattensize + sizeof(xfer_server_register_dormant_node); msgsize = flattensize + sizeof(xfer_server_register_dormant_node);
msg = (xfer_server_register_dormant_node *) malloc(msgsize); msg = (xfer_server_register_dormant_node *) malloc(msgsize);
msg->purge_id = purge_id; // the server should remove previously registered "dormant_flavor_info"s
// during the first update, but after the first iteration, we don't want
// the server to anymore remove old dormant_flavor_infos;
msg->purge_id = (i == 0) ? addon_id : 0;
msg->dfi_type = dfi.TypeCode(); msg->dfi_type = dfi.TypeCode();
msg->dfi_size = flattensize; msg->dfi_size = flattensize;
dfi.Flatten(&(msg->dfi),flattensize); dfi.Flatten(&(msg->dfi),flattensize);
@@ -198,11 +218,12 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon)
} }
free(msg); free(msg);
// after the first iteration, we don't want the server to anymore remove our dfis;
if (purge_id != 0)
purge_id = 0;
} }
// XXX parameter list is (media_addon_id addonid, int32 newcount, int32 gonecount)
// XXX we currently pretend that all old flavors have been removed, this could
// XXX probably be done in a smarter way
BPrivate::media::notifications::FlavorsChanged(addon_id, newflavorcount, oldflavorcount);
} }
void void
@@ -230,6 +251,7 @@ MediaAddonServer::AddOnAdded(const char *path, ino_t file_node)
printf("MediaAddonServer::AddOnAdded: loading finished, id %d\n",(int)id); printf("MediaAddonServer::AddOnAdded: loading finished, id %d\n",(int)id);
filemap->Insert(file_node, id); filemap->Insert(file_node, id);
flavorcountmap->Insert(id, 0);
ScanAddOnFlavors(addon); ScanAddOnFlavors(addon);
@@ -293,6 +315,7 @@ MediaAddonServer::AddOnRemoved(ino_t file_node)
return; return;
} }
filemap->Remove(file_node); filemap->Remove(file_node);
flavorcountmap->Remove(id);
_DormantNodeManager->UnregisterAddon(id); _DormantNodeManager->UnregisterAddon(id);
} }