From f4925104822c0990c8fc7b99144512294827b3cf Mon Sep 17 00:00:00 2001 From: beveloper Date: Wed, 2 Oct 2002 01:04:48 +0000 Subject: [PATCH] changed media kit internal messaging and notification support git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1338 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/media/DataExchange.h | 81 +++++ headers/private/media/NotificationManager.h | 79 ----- headers/private/media/Notifications.h | 87 +++++ src/kits/media/Buffer.cpp | 6 +- src/kits/media/BufferGroup.cpp | 2 +- src/kits/media/Controllable.cpp | 8 +- src/kits/media/DataExchange.cpp | 82 +++++ src/kits/media/Jamfile | 3 +- src/kits/media/MediaNode.cpp | 23 +- src/kits/media/MediaRoster.cpp | 104 ++---- src/kits/media/NotificationManager.cpp | 336 -------------------- src/kits/media/Notifications.cpp | 261 +++++++++++++++ src/servers/media/NodeManager.cpp | 12 + src/servers/media/NodeManager.h | 5 + src/servers/media/ServerInterface.h | 25 +- src/servers/media/media_server.cpp | 7 +- src/servers/media_addon/main.cpp | 63 ++-- 17 files changed, 639 insertions(+), 545 deletions(-) create mode 100644 headers/private/media/DataExchange.h delete mode 100644 headers/private/media/NotificationManager.h create mode 100644 headers/private/media/Notifications.h create mode 100644 src/kits/media/DataExchange.cpp delete mode 100644 src/kits/media/NotificationManager.cpp create mode 100644 src/kits/media/Notifications.cpp diff --git a/headers/private/media/DataExchange.h b/headers/private/media/DataExchange.h new file mode 100644 index 0000000000..581e08cc7d --- /dev/null +++ b/headers/private/media/DataExchange.h @@ -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 +#include +#include +#include + +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 diff --git a/headers/private/media/NotificationManager.h b/headers/private/media/NotificationManager.h deleted file mode 100644 index 1b11522a2f..0000000000 --- a/headers/private/media/NotificationManager.h +++ /dev/null @@ -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 ¬ifyHandler, const media_node &node, notification_type_mask mask); - status_t Unregister(const BMessenger ¬ifyHandler, 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 diff --git a/headers/private/media/Notifications.h b/headers/private/media/Notifications.h new file mode 100644 index 0000000000..3ef54bc10a --- /dev/null +++ b/headers/private/media/Notifications.h @@ -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 ¬ifyHandler, const media_node &node, int32 notification); + + // called by BMediaRoster::StopWatching() + status_t Unregister(const BMessenger ¬ifyHandler, 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 diff --git a/src/kits/media/Buffer.cpp b/src/kits/media/Buffer.cpp index c8cce720c9..8e4e347878 100644 --- a/src/kits/media/Buffer.cpp +++ b/src/kits/media/Buffer.cpp @@ -177,7 +177,7 @@ BBuffer::BBuffer(const buffer_clone_info & info) : BMessage request(MEDIA_SERVER_GET_SHARED_BUFFER_AREA); BMessage reply; - if (MediaKitPrivate::QueryServer(&request, &reply) != B_OK) + if (QueryServer(&request, &reply) != B_OK) return; id = reply.FindInt32("area"); @@ -204,7 +204,7 @@ BBuffer::BBuffer(const buffer_clone_info & info) : // until the last buffer has been unregistered // 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; // the response from media server contains enough information @@ -245,7 +245,7 @@ BBuffer::~BBuffer() // when the last clone of this buffer is gone, // media_server will also remove it's cached area - MediaKitPrivate::QueryServer(&unregister, &response); + QueryServer(&unregister, &response); delete_area(fArea); } diff --git a/src/kits/media/BufferGroup.cpp b/src/kits/media/BufferGroup.cpp index 8397906d7f..3a307c4f95 100644 --- a/src/kits/media/BufferGroup.cpp +++ b/src/kits/media/BufferGroup.cpp @@ -37,7 +37,7 @@ BBufferGroup::InitBufferGroup() BMessage request(MEDIA_SERVER_GET_SHARED_BUFFER_AREA); BMessage reply; - fInitError = MediaKitPrivate::QueryServer(&request, &reply); + fInitError = QueryServer(&request, &reply); if (fInitError != B_OK) return fInitError; diff --git a/src/kits/media/Controllable.cpp b/src/kits/media/Controllable.cpp index 9f1617df74..d4764d27c9 100644 --- a/src/kits/media/Controllable.cpp +++ b/src/kits/media/Controllable.cpp @@ -5,7 +5,7 @@ ***********************************************************************/ #include #include "debug.h" -#include "NotificationManager.h" +#include "Notifications.h" /************************************************************* * protected BControllable @@ -60,6 +60,8 @@ status_t BControllable::SetParameterWeb(BParameterWeb *web) { UNIMPLEMENTED(); + + BPrivate::media::notifications::WebChanged(Node()); return B_ERROR; } @@ -80,7 +82,7 @@ status_t BControllable::BroadcastChangedParameter(int32 id) { 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) { CALLED(); - return _NotificationManager->NewParameterValue(Node(), id, when, newValue, valueSize); + return BPrivate::media::notifications::NewParameterValue(Node(), id, when, newValue, valueSize); } diff --git a/src/kits/media/DataExchange.cpp b/src/kits/media/DataExchange.cpp new file mode 100644 index 0000000000..db0142bb17 --- /dev/null +++ b/src/kits/media/DataExchange.cpp @@ -0,0 +1,82 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#include +#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 + diff --git a/src/kits/media/Jamfile b/src/kits/media/Jamfile index 2a2f43dd77..9420ceb30c 100644 --- a/src/kits/media/Jamfile +++ b/src/kits/media/Jamfile @@ -42,9 +42,10 @@ SharedLibrary media : TimeSource.cpp # Internal Functionality + DataExchange.cpp PortPool.cpp DormantNodeManager.cpp - NotificationManager.cpp + Notifications.cpp SystemTimeSource.cpp BufferIdCache.cpp SharedBufferList.cpp diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp index 65e0673519..a6bc2b3453 100644 --- a/src/kits/media/MediaNode.cpp +++ b/src/kits/media/MediaNode.cpp @@ -14,7 +14,7 @@ #include "SystemTimeSource.h" #include "debug.h" #include "ServerInterface.h" -#include "NotificationManager.h" +#include "Notifications.h" // don't rename this one, it's used and exported for binary compatibility int32 BMediaNode::_m_changeTag = 0; @@ -214,9 +214,26 @@ BMediaNode::ReportError(node_error what, const BMessage *info) { 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 // 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. // 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 will be notified that your node stopped (automatically, no less) diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index 97510eb1f4..5608d35da3 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -16,11 +16,15 @@ #include "debug.h" #include "PortPool.h" #include "ServerInterface.h" +#include "DataExchange.h" #include "DormantNodeManager.h" -#include "NotificationManager.h" +#include "Notifications.h" -static BMessenger *ServerMessenger = 0; -static team_id team; +using namespace BPrivate::media; + +namespace BPrivate { namespace media { + extern team_id team; +}; }; // the BMediaRoster destructor is private, // but _DefaultDeleter is a friend class of @@ -31,48 +35,15 @@ public: void Delete() { delete BMediaRoster::_sDefault; } }; +_DefaultDeleter _deleter; 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 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) { if (out_node == NULL) @@ -154,7 +125,7 @@ BMediaRoster::GetVideoInput(media_node * out_node) return MediaKitPrivate::GetNode(VIDEO_INPUT, out_node); } - + status_t BMediaRoster::GetAudioInput(media_node * out_node) { @@ -837,8 +808,7 @@ BMediaRoster::StartWatching(const BMessenger & where) TRACE("BMediaRoster::StartWatching: messenger invalid!\n"); return B_BAD_VALUE; } - return _NotificationManager->Register(where, media_node::null, - BPrivate::media::NotificationManager::notification_basic); + return BPrivate::media::notifications::Register(where, media_node::null, B_MEDIA_WILDCARD); } @@ -851,12 +821,11 @@ BMediaRoster::StartWatching(const BMessenger & where, TRACE("BMediaRoster::StartWatching: messenger invalid!\n"); return B_BAD_VALUE; } - if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) { + if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) { TRACE("BMediaRoster::StartWatching: notificationType invalid!\n"); return B_BAD_VALUE; } - return _NotificationManager->Register(where, media_node::null, - BPrivate::media::NotificationManager::NotificationType2Mask(notificationType)); + return BPrivate::media::notifications::Register(where, media_node::null, notificationType); } @@ -874,12 +843,11 @@ BMediaRoster::StartWatching(const BMessenger & where, TRACE("BMediaRoster::StartWatching: node invalid!\n"); 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"); return B_BAD_VALUE; } - return _NotificationManager->Register(where, node, - BPrivate::media::NotificationManager::NotificationType2Mask(notificationType)); + return BPrivate::media::notifications::Register(where, node, notificationType); } @@ -888,8 +856,7 @@ BMediaRoster::StopWatching(const BMessenger & where) { CALLED(); // messenger may already be invalid, so we don't check this - return _NotificationManager->Unregister(where, media_node::null, - BPrivate::media::NotificationManager::notification_basic); + return BPrivate::media::notifications::Unregister(where, media_node::null, B_MEDIA_WILDCARD); } @@ -899,12 +866,11 @@ BMediaRoster::StopWatching(const BMessenger & where, { CALLED(); // 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"); return B_BAD_VALUE; } - return _NotificationManager->Unregister(where, media_node::null, - BPrivate::media::NotificationManager::NotificationType2Mask(notificationType)); + return BPrivate::media::notifications::Unregister(where, media_node::null, notificationType); } @@ -919,12 +885,11 @@ BMediaRoster::StopWatching(const BMessenger & where, TRACE("BMediaRoster::StopWatching: node invalid!\n"); 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"); return B_BAD_VALUE; } - return _NotificationManager->Unregister(where, node, - BPrivate::media::NotificationManager::NotificationType2Mask(notificationType)); + return BPrivate::media::notifications::Unregister(where, node, notificationType); } @@ -1106,27 +1071,16 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info, // forward this request into the media_addon_server, // which in turn will call InstantiateDormantNode() // to create it there localy - xfer_addonserver_instantiate_dormant_node msg; - xfer_addonserver_instantiate_dormant_node_reply reply; - port_id port; + request_addonserver_instantiate_dormant_node request; + reply_addonserver_instantiate_dormant_node reply; status_t rv; - int32 code; - port = find_port("media_addon_server port"); - if (port <= B_OK) - return B_ERROR; - msg.info = in_info; - 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; + + request.info = in_info; + rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request, sizeof(request), &reply, sizeof(reply)); + if (rv == B_OK) { + *out_node = reply.node; } - rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); - _PortPool->PutPort(msg.reply_port); - if (rv < B_OK) - return rv; - *out_node = reply.node; - return reply.result; + return rv; } // XXX SOMETHING IS VERY WRONG HERE @@ -1492,7 +1446,7 @@ BMediaRoster::~BMediaRoster() BMessage msg(MEDIA_SERVER_UNREGISTER_APP); BMessage reply; msg.AddInt32("team",team); - ServerMessenger->SendMessage(&msg,&reply); + QueryServer(&msg, &reply); } @@ -1529,7 +1483,7 @@ BMediaRoster::BMediaRoster() : BMessage msg(MEDIA_SERVER_REGISTER_APP); BMessage reply; msg.AddInt32("team",team); - ServerMessenger->SendMessage(&msg,&reply); + QueryServer(&msg,&reply); } /* static */ status_t diff --git a/src/kits/media/NotificationManager.cpp b/src/kits/media/NotificationManager.cpp deleted file mode 100644 index 3d0c91ce6a..0000000000 --- a/src/kits/media/NotificationManager.cpp +++ /dev/null @@ -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 -#include -#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 ¬ifyHandler, const media_node &node, notification_type_mask mask) -{ - CALLED(); - BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS); - - return SendMessageToMediaServer(&msg); -} - - -status_t -NotificationManager::Unregister(const BMessenger ¬ifyHandler, 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 diff --git a/src/kits/media/Notifications.cpp b/src/kits/media/Notifications.cpp new file mode 100644 index 0000000000..18cebb2a44 --- /dev/null +++ b/src/kits/media/Notifications.cpp @@ -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 +#include +#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) +{ + 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 ¬ifyHandler, 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 diff --git a/src/servers/media/NodeManager.cpp b/src/servers/media/NodeManager.cpp index 0440e9aa60..c11ade54e8 100644 --- a/src/servers/media/NodeManager.cpp +++ b/src/servers/media/NodeManager.cpp @@ -22,6 +22,18 @@ NodeManager::~NodeManager() 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 NodeManager::RegisterAddon(const entry_ref &ref, media_addon_id *newid) { diff --git a/src/servers/media/NodeManager.h b/src/servers/media/NodeManager.h index 7261bf710e..d7758237ce 100644 --- a/src/servers/media/NodeManager.h +++ b/src/servers/media/NodeManager.h @@ -26,6 +26,11 @@ public: status_t LoadState(); 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 RemoveDormantFlavorInfo(media_addon_id id); void RegisterAddon(const entry_ref &ref, media_addon_id *newid); diff --git a/src/servers/media/ServerInterface.h b/src/servers/media/ServerInterface.h index 385a30850b..c6e180c37d 100644 --- a/src/servers/media/ServerInterface.h +++ b/src/servers/media/ServerInterface.h @@ -18,11 +18,6 @@ enum { MEDIA_SERVER_REGISTER_BUFFER, MEDIA_SERVER_UNREGISTER_BUFFER, - // BMediaRoster notification service - MEDIA_SERVER_REQUEST_NOTIFICATIONS, - MEDIA_SERVER_CANCEL_NOTIFICATIONS, - MEDIA_SERVER_SEND_NOTIFICATIONS, - // Something else MEDIA_SERVER_SET_VOLUME, MEDIA_SERVER_GET_VOLUME, @@ -588,22 +583,10 @@ struct xfer_consumer_seek_tag_requested_reply status_t result; }; -struct xfer_addonserver_instantiate_dormant_node -{ - 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 -{ +namespace BPrivate { namespace media { namespace dataexchange { status_t QueryServer(BMessage *query, BMessage *reply); -}; +}; }; }; + +using namespace BPrivate::media::dataexchange; #endif diff --git a/src/servers/media/media_server.cpp b/src/servers/media/media_server.cpp index e1a3cf4aac..d7cd2acbc9 100644 --- a/src/servers/media/media_server.cpp +++ b/src/servers/media/media_server.cpp @@ -6,6 +6,7 @@ #include #include "NotificationProcessor.h" #include "ServerInterface.h" +#include "DataExchange.h" #include "BufferManager.h" #include "NodeManager.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_REGISTER_BUFFER: RegisterBuffer(msg); break; case MEDIA_SERVER_UNREGISTER_BUFFER: UnregisterBuffer(msg); break; - case MEDIA_SERVER_REQUEST_NOTIFICATIONS: fNotificationProcessor->RequestNotifications(msg); break; - case MEDIA_SERVER_CANCEL_NOTIFICATIONS: fNotificationProcessor->CancelNotifications(msg); break; - case MEDIA_SERVER_SEND_NOTIFICATIONS: fNotificationProcessor->SendNotifications(msg); break; + case MEDIA_SERVER_REQUEST_NOTIFICATIONS: fNotificationProcessor->EnqueueMessage(msg); break; + case MEDIA_SERVER_CANCEL_NOTIFICATIONS: fNotificationProcessor->EnqueueMessage(msg); break; + case MEDIA_SERVER_SEND_NOTIFICATIONS: fNotificationProcessor->EnqueueMessage(msg); break; case MEDIA_SERVER_GET_NODE_ID: GetNodeID(msg); break; diff --git a/src/servers/media_addon/main.cpp b/src/servers/media_addon/main.cpp index 0011a32dcb..336d80d34f 100644 --- a/src/servers/media_addon/main.cpp +++ b/src/servers/media_addon/main.cpp @@ -15,9 +15,11 @@ #include "debug.h" #include "TMap.h" #include "ServerInterface.h" +#include "DataExchange.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); @@ -37,7 +39,8 @@ public: void ScanAddOnFlavors(BMediaAddOn *addon); - Map *filemap; + Map *filemap; + Map *flavorcountmap; BMediaRoster *mediaroster; ino_t DirNodeSystem; @@ -50,7 +53,8 @@ MediaAddonServer::MediaAddonServer(const char *sig) : BApplication(sig) { mediaroster = BMediaRoster::Roster(); - filemap = new Map; + filemap = new Map; + flavorcountmap = new Map; control_port = create_port(64,"media_addon_server port"); control_thread = spawn_thread(controlthread,"media_addon_server control",12,this); resume_thread(control_thread); @@ -68,6 +72,7 @@ MediaAddonServer::~MediaAddonServer() _DormantNodeManager->UnregisterAddon(id); delete filemap; + delete flavorcountmap; } void @@ -76,10 +81,10 @@ MediaAddonServer::HandleMessage(int32 code, void *data, size_t size) switch (code) { case ADDONSERVER_INSTANTIATE_DORMANT_NODE: { - const xfer_addonserver_instantiate_dormant_node *msg = (const xfer_addonserver_instantiate_dormant_node *)data; - xfer_addonserver_instantiate_dormant_node_reply reply; + const request_addonserver_instantiate_dormant_node *msg = (const request_addonserver_instantiate_dormant_node *)data; + reply_addonserver_instantiate_dormant_node reply; reply.result = mediaroster->InstantiateDormantNode(msg->info, &reply.node); - write_port(msg->reply_port, 0, &reply, sizeof(reply)); + msg->SendReply(&reply, sizeof(reply)); break; } @@ -140,10 +145,13 @@ MediaAddonServer::ReadyToRun() void MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon) { - int flavorcount; - media_addon_id purge_id; + int32 *flavorcount; + int32 oldflavorcount; + int32 newflavorcount; + media_addon_id addon_id; port_id port; status_t rv; + bool b; ASSERT(addon); ASSERT(addon->AddonID() > 0); @@ -156,13 +164,21 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon) return; } - // the server should remove previously registered "dormant_flavor_info"s - purge_id = addon->AddonID(); + // cache the media_addon_id in a local variable to avoid + // 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(); - printf("%d flavors:\n",flavorcount); - - for (int i = 0; i < flavorcount; i++) { + // during the first update (i == 0), the server removes old dormant_flavor_infos + for (int i = 0; i < newflavorcount; i++) { const flavor_info *info; printf("flavor %d:\n",i); if (B_OK != addon->GetFlavorAt(i, &info)) { @@ -174,7 +190,7 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon) dormant_flavor_info dfi; dfi = *info; - dfi.node_info.addon = addon->AddonID(); + dfi.node_info.addon = addon_id; dfi.node_info.flavor_id = info->internal_id; strncpy(dfi.node_info.name, info->name, B_MEDIA_NAME_LENGTH - 1); 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); 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_size = flattensize; dfi.Flatten(&(msg->dfi),flattensize); @@ -198,11 +218,12 @@ MediaAddonServer::ScanAddOnFlavors(BMediaAddOn *addon) } 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 @@ -230,6 +251,7 @@ MediaAddonServer::AddOnAdded(const char *path, ino_t file_node) printf("MediaAddonServer::AddOnAdded: loading finished, id %d\n",(int)id); filemap->Insert(file_node, id); + flavorcountmap->Insert(id, 0); ScanAddOnFlavors(addon); @@ -293,6 +315,7 @@ MediaAddonServer::AddOnRemoved(ino_t file_node) return; } filemap->Remove(file_node); + flavorcountmap->Remove(id); _DormantNodeManager->UnregisterAddon(id); }