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:
@@ -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 ¬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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
***********************************************************************/
|
||||
#include <Controllable.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ¬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
|
||||
@@ -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 ¬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
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <Autolock.h>
|
||||
#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;
|
||||
|
||||
@@ -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<ino_t,media_addon_id> *filemap;
|
||||
Map<ino_t, media_addon_id> *filemap;
|
||||
Map<media_addon_id, int32> *flavorcountmap;
|
||||
|
||||
BMediaRoster *mediaroster;
|
||||
ino_t DirNodeSystem;
|
||||
@@ -50,7 +53,8 @@ MediaAddonServer::MediaAddonServer(const char *sig) :
|
||||
BApplication(sig)
|
||||
{
|
||||
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_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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user