From 1299bfb29f6155daaa6117fec04f9054e0dc24b6 Mon Sep 17 00:00:00 2001 From: beveloper Date: Tue, 8 Oct 2002 23:59:43 +0000 Subject: [PATCH] added real media_server node management, removed bugs, added debug output git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1467 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/media/DataExchange.h | 10 +- headers/private/media/TList.h | 13 + headers/private/media/TMap.h | 3 +- src/kits/media/DataExchange.cpp | 4 + src/kits/media/MediaNode.cpp | 24 +- src/kits/media/MediaRoster.cpp | 46 +++- src/kits/media/Notifications.cpp | 1 + src/servers/media/AppManager.cpp | 4 + src/servers/media/AppManager.h | 4 + src/servers/media/BufferManager.cpp | 4 + src/servers/media/BufferManager.h | 4 + src/servers/media/NodeManager.cpp | 284 +++++++++++++++++++++- src/servers/media/NodeManager.h | 25 +- src/servers/media/NotificationManager.cpp | 13 + src/servers/media/NotificationManager.h | 4 + src/servers/media/Queue.cpp | 2 +- 16 files changed, 399 insertions(+), 46 deletions(-) diff --git a/headers/private/media/DataExchange.h b/headers/private/media/DataExchange.h index d27ac09931..678b87651a 100644 --- a/headers/private/media/DataExchange.h +++ b/headers/private/media/DataExchange.h @@ -39,7 +39,7 @@ struct request_data { port_id reply_port; - void SendReply(status_t result, reply_data *reply, int replysize) const; + status_t SendReply(status_t result, reply_data *reply, int replysize) const; }; // The base struct used for all raw replys @@ -233,8 +233,8 @@ struct server_publish_inputs_request : public request_data media_node node; int32 count; area_id area; // if count > MAX_INPUTS, inputs are in the area - // area is created in the server, and also deleted - // in the server after the reply has been received + // area is created in the library, and also deleted + // in the library after the reply has been received media_input inputs[MAX_INPUTS]; }; @@ -247,6 +247,8 @@ struct server_publish_outputs_request : public request_data media_node node; int32 count; area_id area; // if count > MAX_OUTPUTS, outputs are in the area + // area is created in the library, and also deleted + // in the library after the reply has been received media_output outputs[MAX_OUTPUTS]; }; @@ -366,7 +368,7 @@ struct server_get_live_nodes_reply : public reply_data { int32 count; area_id area; // if count > MAX_LIVE_INFO, live_node_infos are in the area - // area is created in the server, but deleted in the application + // area is created in the server, but deleted in the library live_node_info live_info[MAX_LIVE_INFO]; }; diff --git a/headers/private/media/TList.h b/headers/private/media/TList.h index 1b5374bbee..2324bc17b5 100644 --- a/headers/private/media/TList.h +++ b/headers/private/media/TList.h @@ -22,6 +22,14 @@ public: *v = list[index]; return true; } + + bool GetPointerAt(int32 index, value **v) + { + if (index < 0 || index >= count) + return false; + *v = &list[index]; + return true; + } // you can't Remove() while iterating through the map using GetAt() bool Remove(int32 index) @@ -33,6 +41,11 @@ public: list[index] = list[count]; return true; } + + void MakeEmpty() + { + count = 0; + } private: enum { MAXENT = 64 }; diff --git a/headers/private/media/TMap.h b/headers/private/media/TMap.h index 20727392c5..9f5bda0589 100644 --- a/headers/private/media/TMap.h +++ b/headers/private/media/TMap.h @@ -6,7 +6,7 @@ template class Map public: Map() : count(0) {} - void Insert(const key &k, const value &v) + bool Insert(const key &k, const value &v) { value temp; if (count == MAXENT) debugger("template Map out of memory"); @@ -14,6 +14,7 @@ public: list[count].k = k; list[count].v = v; count++; + return true; } bool Get(const key &k, value *v) diff --git a/src/kits/media/DataExchange.cpp b/src/kits/media/DataExchange.cpp index 10d34ce6c9..06ae0fdf36 100644 --- a/src/kits/media/DataExchange.cpp +++ b/src/kits/media/DataExchange.cpp @@ -32,6 +32,10 @@ public: MediaServerMessenger = new BMessenger(NEW_MEDIA_SERVER_SIGNATURE); MediaServerPort = find_port("media_server port"); MediaAddonServerPort = find_port("media_addon_server port"); + + thread_info info; + get_thread_info(find_thread(NULL), &info); + team = info.team; } ~initit() { diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp index a0ff338503..f23848bc45 100644 --- a/src/kits/media/MediaNode.cpp +++ b/src/kits/media/MediaNode.cpp @@ -496,28 +496,16 @@ BMediaNode::HandleBadMessage(int32 code, CALLED(); TRACE("BMediaNode::HandleBadMessage: code %#08lx, buffer %p, size %ld\n", code, buffer, size); - switch (code) { - default: - { - TRACE("BMediaNode::HandleBadMessage: unknown code!\n"); - break; - } - + if (code < 0x1000) { + TRACE("BMediaNode::HandleBadMessage: unknown code!\n"); + } else { /* All messages targeted to nodes should be handled here, * messages targetted to the wrong node should be handled * by returning an error, not by stalling the sender. */ - case CONSUMER_ACCEPT_FORMAT: - case CONSUMER_CONNECTED: - case PRODUCER_FORMAT_PROPOSAL: - case PRODUCER_PREPARE_TO_CONNECT: - case PRODUCER_CONNECT: - { - const request_data *request = static_cast(buffer); - reply_data reply; - request->SendReply(B_ERROR, &reply, sizeof(reply)); - break; - } + const request_data *request = static_cast(buffer); + reply_data reply; + request->SendReply(B_ERROR, &reply, sizeof(reply)); } } diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index af8a165301..2ba8a1ae6f 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -17,6 +17,7 @@ #include "debug.h" #include "TStack.h" #include "PortPool.h" +#include "SystemTimeSource.h" #include "ServerInterface.h" #include "DataExchange.h" #include "DormantNodeManager.h" @@ -432,8 +433,8 @@ BMediaRoster::ReleaseNode(const media_node & node) BTimeSource * BMediaRoster::MakeTimeSourceFor(const media_node & for_node) { - UNIMPLEMENTED(); - return 0; + BROKEN(); + return new _SysTimeSource(); // XXX fix this } @@ -867,7 +868,7 @@ BMediaRoster::GetLiveNodeInfo(const media_node & node, request.node = node; - rv = QueryAddonServer(SERVER_GET_LIVE_NODE_INFO, &request, sizeof(request), &reply, sizeof(reply)); + rv = QueryServer(SERVER_GET_LIVE_NODE_INFO, &request, sizeof(request), &reply, sizeof(reply)); if (rv != B_OK) return rv; @@ -915,6 +916,7 @@ BMediaRoster::GetLiveNodes(live_node_info * out_live_nodes, rv = QueryServer(SERVER_GET_LIVE_NODES, &request, sizeof(request), &reply, sizeof(reply)); if (rv != B_OK) { TRACE("BMediaRoster::GetLiveNodes failed\n"); + *io_total_count = 0; return rv; } @@ -926,6 +928,7 @@ BMediaRoster::GetLiveNodes(live_node_info * out_live_nodes, if (clone < B_OK) { TRACE("BMediaRoster::GetLiveNodes failed to clone area, %#lx\n", clone); delete_area(reply.area); + *io_total_count = 0; return B_ERROR; } @@ -963,11 +966,12 @@ BMediaRoster::GetFreeInputsFor(const media_node & node, media_input *input; status_t rv; + *out_total_count = 0; + rv = GetAllInputs(node, &stack); if (B_OK != rv) return rv; - *out_total_count = 0; for (int32 i = 0; stack.GetPointerAt(i, &input); i++) { if (filter_type != B_MEDIA_UNKNOWN_TYPE && filter_type != input->format.type) continue; // media_type used, but doesn't match @@ -1001,11 +1005,12 @@ BMediaRoster::GetConnectedInputsFor(const media_node & node, media_input *input; status_t rv; + *out_total_count = 0; + rv = GetAllInputs(node, &stack); if (B_OK != rv) return rv; - *out_total_count = 0; for (int32 i = 0; stack.GetPointerAt(i, &input); i++) { if (input->source == media_source::null) continue; // consumer source not connected @@ -1037,11 +1042,12 @@ BMediaRoster::GetAllInputsFor(const media_node & node, media_input *input; status_t rv; + *out_total_count = 0; + rv = GetAllInputs(node, &stack); if (B_OK != rv) return rv; - *out_total_count = 0; for (int32 i = 0; stack.GetPointerAt(i, &input); i++) { out_inputs[i] = *input; *out_total_count += 1; @@ -1072,11 +1078,12 @@ BMediaRoster::GetFreeOutputsFor(const media_node & node, media_output *output; status_t rv; + *out_total_count = 0; + rv = GetAllOutputs(node, &stack); if (B_OK != rv) return rv; - *out_total_count = 0; for (int32 i = 0; stack.GetPointerAt(i, &output); i++) { if (filter_type != B_MEDIA_UNKNOWN_TYPE && filter_type != output->format.type) continue; // media_type used, but doesn't match @@ -1110,11 +1117,12 @@ BMediaRoster::GetConnectedOutputsFor(const media_node & node, media_output *output; status_t rv; + *out_total_count = 0; + rv = GetAllOutputs(node, &stack); if (B_OK != rv) return rv; - *out_total_count = 0; for (int32 i = 0; stack.GetPointerAt(i, &output); i++) { if (output->destination == media_destination::null) continue; // producer destination not connected @@ -1146,11 +1154,12 @@ BMediaRoster::GetAllOutputsFor(const media_node & node, media_output *output; status_t rv; + *out_total_count = 0; + rv = GetAllOutputs(node, &stack); if (B_OK != rv) return rv; - *out_total_count = 0; for (int32 i = 0; stack.GetPointerAt(i, &output); i++) { out_outputs[i] = *output; *out_total_count += 1; @@ -1282,6 +1291,8 @@ BMediaRoster::RegisterNode(BMediaNode * node) request.kinds = node->Kinds(); request.port = node->ControlPort(); request.team = team; + + TRACE("BMediaRoster::RegisterNode: sending SERVER_REGISTER_NODE: port %ld, kinds %#Lx, team %ld, name '%s'\n", request.port, request.kinds, request.team, request.name); rv = QueryServer(SERVER_REGISTER_NODE, &request, sizeof(request), &reply, sizeof(reply)); if (rv != B_OK) { @@ -1294,9 +1305,13 @@ BMediaRoster::RegisterNode(BMediaNode * node) ASSERT(reply.nodeid == node->Node().node); ASSERT(reply.nodeid == node->ID()); + TRACE("BMediaRoster::RegisterNode: before callback: port %ld, name '%s'\n", node->ControlPort(), node->Name()); + // call the callback node->NodeRegistered(); + TRACE("BMediaRoster::RegisterNode: after callback: port %ld, name '%s'\n", node->ControlPort(), node->Name()); + // register existing inputs and outputs with the // media_server, this allows GetLiveNodes() to work // with created, but unconnected nodes. @@ -1309,6 +1324,8 @@ BMediaRoster::RegisterNode(BMediaNode * node) if (B_OK == GetAllInputs(node->Node(), &stack)) PublishInputs(node->Node(), &stack); } + BPrivate::media::notifications::NodesCreated(&reply.nodeid, 1); + TRACE("BMediaRoster::RegisterNode: registered node %s, id %ld, addon %ld, flavor %ld\n", node->Name(), node->ID(), addon_id, addon_flavor_id); @@ -1339,6 +1356,9 @@ BMediaRoster::UnregisterNode(BMediaNode * node) request.nodeid = node->ID(); request.team = team; + // send a notification + BPrivate::media::notifications::NodesDeleted(&request.nodeid, 1); + rv = QueryServer(SERVER_UNREGISTER_NODE, &request, sizeof(request), &reply, sizeof(reply)); if (rv != B_OK) { TRACE("BMediaRoster::UnregisterNode: failed to unregister node %s (error %#lx)\n", node->Name(), rv); @@ -1348,7 +1368,7 @@ BMediaRoster::UnregisterNode(BMediaNode * node) if (reply.addon_id != -1) _DormantNodeManager->PutAddon(reply.addon_id); - // we are a friend class of BMediaNode and initilize this member variable + // we are a friend class of BMediaNode and invalidate this member variable node->fNodeID = -2; return B_OK; @@ -1559,7 +1579,9 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info, printf("BMediaRoster::InstantiateDormantNode: GetAddon failed\n"); return B_ERROR; } - flavor_info temp; + flavor_info temp; // XXX fix this! + temp.name = "XXX flavor_info name"; + temp.info = "XXX flavor_info info"; temp.internal_id = in_info.flavor_id; node = addon->InstantiateNodeFor(&temp, &config, &out_error); if (!node) { @@ -1601,7 +1623,7 @@ BMediaRoster::GetDormantNodeFor(const media_node & node, request.node = node; - rv = QueryAddonServer(SERVER_GET_DORMANT_NODE_FOR, &request, sizeof(request), &reply, sizeof(reply)); + rv = QueryServer(SERVER_GET_DORMANT_NODE_FOR, &request, sizeof(request), &reply, sizeof(reply)); if (rv != B_OK) return rv; diff --git a/src/kits/media/Notifications.cpp b/src/kits/media/Notifications.cpp index 18cebb2a44..2fdde5a714 100644 --- a/src/kits/media/Notifications.cpp +++ b/src/kits/media/Notifications.cpp @@ -13,6 +13,7 @@ */ #include #include +#define DEBUG 1 #include "debug.h" #include "DataExchange.h" #include "Notifications.h" diff --git a/src/servers/media/AppManager.cpp b/src/servers/media/AppManager.cpp index 6072427547..b68f74260f 100644 --- a/src/servers/media/AppManager.cpp +++ b/src/servers/media/AppManager.cpp @@ -1,3 +1,7 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include #include #include diff --git a/src/servers/media/AppManager.h b/src/servers/media/AppManager.h index 9d3d3aebe5..619d7fa5a5 100644 --- a/src/servers/media/AppManager.h +++ b/src/servers/media/AppManager.h @@ -1,3 +1,7 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include #include diff --git a/src/servers/media/BufferManager.cpp b/src/servers/media/BufferManager.cpp index 49bd487ed5..edefbecd0c 100644 --- a/src/servers/media/BufferManager.cpp +++ b/src/servers/media/BufferManager.cpp @@ -1,3 +1,7 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include #include #include "BufferManager.h" diff --git a/src/servers/media/BufferManager.h b/src/servers/media/BufferManager.h index 1351eb84fa..6b6ec895fb 100644 --- a/src/servers/media/BufferManager.h +++ b/src/servers/media/BufferManager.h @@ -1,3 +1,7 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ struct _shared_buffer_list; class BufferManager diff --git a/src/servers/media/NodeManager.cpp b/src/servers/media/NodeManager.cpp index 6a0303bc49..51a987d623 100644 --- a/src/servers/media/NodeManager.cpp +++ b/src/servers/media/NodeManager.cpp @@ -1,31 +1,58 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include #include #include #include #include #include +#define DEBUG 1 +#include #include "debug.h" #include "NodeManager.h" // XXX locking is missing NodeManager::NodeManager() : - nextaddonid(1) + nextaddonid(1), + nextnodeid(1) { fDormantFlavorList = new List; fAddonPathMap = new Map; + fRegisteredNodeMap = new Map; } + NodeManager::~NodeManager() { delete fDormantFlavorList; delete fAddonPathMap; + delete fRegisteredNodeMap; } status_t NodeManager::RegisterNode(media_node_id *nodeid, media_addon_id addon_id, int32 addon_flavor_id, const char *name, uint64 kinds, port_id port, team_id team) { + bool b; + registered_node rn; + rn.nodeid = nextnodeid; + rn.addon_id = addon_id; + rn.addon_flavor_id = addon_flavor_id; + strcpy(rn.name, name); + rn.kinds = kinds; + rn.port = port; + rn.team = team; + rn.globalrefcount = 1; + rn.teamrefcount.Insert(team, 1); + + b = fRegisteredNodeMap->Insert(nextnodeid, rn); + ASSERT(b); + *nodeid = nextnodeid; + nextnodeid += 1; + TRACE("NodeManager::RegisterNode: node %ld, addon_id %ld, flavor_id %ld, name '%s', kinds %#Lx, port %ld, team %ld\n", *nodeid, addon_id, addon_flavor_id, name, kinds, port, team); return B_OK; } @@ -33,6 +60,83 @@ NodeManager::RegisterNode(media_node_id *nodeid, media_addon_id addon_id, int32 status_t NodeManager::UnregisterNode(media_addon_id *addon_id, media_node_id nodeid, team_id team) { + bool b; + registered_node *rn; + TRACE("NodeManager::UnregisterNode enter: node %ld, team %ld\n", nodeid, team); + b = fRegisteredNodeMap->GetPointer(nodeid, &rn); + if (!b) { + TRACE("!!! NodeManager::UnregisterNode: Error: couldn't finde node %ld (team %ld)\n", nodeid, team); + return B_ERROR; + } + if (rn->team != team) { + TRACE("!!! NodeManager::UnregisterNode: Error: team %ld tried to unregister node %ld, but it was instantiated by team %ld\n", team, nodeid, rn->team); + return B_ERROR; + } + if (rn->globalrefcount != 1) { + TRACE("!!! NodeManager::UnregisterNode: Error: node %ld, team %ld, globalrefcount %ld\n", nodeid, team, rn->globalrefcount); + //return B_ERROR; + } + *addon_id = rn->addon_id; + b = fRegisteredNodeMap->Remove(nodeid); + ASSERT(b); + TRACE("NodeManager::UnregisterNode leave: node %ld, addon_id %ld, team %ld\n", nodeid, *addon_id, team); + return B_OK; +} + + +status_t +NodeManager::IncrementGlobalRefCount(media_node_id nodeid, team_id team) +{ + registered_node *rn; + bool b; + TRACE("NodeManager::IncrementGlobalRefCount enter: node %ld, team %ld\n", nodeid, team); + b = fRegisteredNodeMap->GetPointer(nodeid, &rn); + if (!b) { + TRACE("!!! NodeManager::IncrementGlobalRefCount: Error: node %ld not found\n", nodeid); + return B_ERROR; + } + int32 *count; + int32 debug_count; + b = rn->teamrefcount.GetPointer(team, &count); + if (b) { + *count += 1; + debug_count = *count; + } else { + b = rn->teamrefcount.Insert(team, 1); + ASSERT(b); + debug_count = 1; + } + rn->globalrefcount += 1; + TRACE("NodeManager::IncrementGlobalRefCount leave: node %ld, team %ld, count %ld, globalcount %ld\n", nodeid, team, debug_count, rn->globalrefcount); + return B_OK; +} + + +status_t +NodeManager::DecrementGlobalRefCount(media_node_id nodeid, team_id team) +{ + registered_node *rn; + bool b; + TRACE("NodeManager::DecrementGlobalRefCount enter: node %ld, team %ld\n", nodeid, team); + b = fRegisteredNodeMap->GetPointer(nodeid, &rn); + if (!b) { + TRACE("!!! NodeManager::DecrementGlobalRefCount: Error: node %ld not found\n", nodeid); + return B_ERROR; + } + int32 *count; + b = rn->teamrefcount.GetPointer(team, &count); + if (!b) { + TRACE("!!! NodeManager::DecrementGlobalRefCount: Error: node %ld has no team %ld references\n", nodeid, team); + return B_ERROR; + } + *count -= 1; + int32 debug_count = *count; + if (*count == 0) { + b = rn->teamrefcount.Remove(team); + ASSERT(b); + } + rn->globalrefcount -= 1; + TRACE("NodeManager::DecrementGlobalRefCount leave: node %ld, team %ld, count %ld, globalcount %ld\n", nodeid, team, debug_count, rn->globalrefcount); return B_OK; } @@ -40,6 +144,26 @@ NodeManager::UnregisterNode(media_addon_id *addon_id, media_node_id nodeid, team status_t NodeManager::GetCloneForId(media_node *node, media_node_id nodeid, team_id team) { + registered_node *rn; + bool b; + TRACE("NodeManager::GetCloneForId enter: node %ld team %ld\n", nodeid, team); + + if (B_OK != IncrementGlobalRefCount(nodeid, team)) { + TRACE("!!! NodeManager::GetCloneForId: Error: couldn't increment ref count, node %ld team %ld\n", nodeid, team); + return B_ERROR; + } + + b = fRegisteredNodeMap->GetPointer(nodeid, &rn); + if (!b) { + TRACE("!!! NodeManager::GetCloneForId: Error: node %ld not found\n", nodeid); + return B_ERROR; + } + + node->node = rn->nodeid; + node->port = rn->port; + node->kind = rn->kinds; + + TRACE("NodeManager::GetCloneForId leave: node %ld team %ld\n", nodeid, team); return B_OK; } @@ -47,13 +171,19 @@ NodeManager::GetCloneForId(media_node *node, media_node_id nodeid, team_id team) status_t NodeManager::GetClone(media_node *node, char *input_name, int32 *input_id, node_type type, team_id team) { - return B_OK; + TRACE("!!! NodeManager::GetClone not implemented\n"); + return B_ERROR; } status_t NodeManager::ReleaseNode(const media_node &node, team_id team) { + TRACE("NodeManager::ReleaseNode enter: node %ld team %ld\n", node.node, team); + if (B_OK != DecrementGlobalRefCount(node.node, team)) { + TRACE("!!! NodeManager::ReleaseNode: Error: couldn't decrement node %ld team %ld ref count\n", node.node, team); + } + TRACE("NodeManager::ReleaseNode leave: node %ld team %ld\n", node.node, team); return B_OK; } @@ -61,6 +191,16 @@ NodeManager::ReleaseNode(const media_node &node, team_id team) status_t NodeManager::PublishInputs(const media_node &node, const media_input *inputs, int32 count) { + registered_node *rn; + bool b; + b = fRegisteredNodeMap->GetPointer(node.node, &rn); + if (!b) { + TRACE("!!! NodeManager::PublishInputs: Error: node %ld not found\n", node.node); + return B_ERROR; + } + rn->inputlist.MakeEmpty(); + for (int32 i = 0; i < count; i++) + rn->inputlist.Insert(inputs[i]); return B_OK; } @@ -68,6 +208,16 @@ NodeManager::PublishInputs(const media_node &node, const media_input *inputs, in status_t NodeManager::PublishOutputs(const media_node &node, const media_output *outputs, int32 count) { + registered_node *rn; + bool b; + b = fRegisteredNodeMap->GetPointer(node.node, &rn); + if (!b) { + TRACE("!!! NodeManager::PublishOutputs: Error: node %ld not found\n", node.node); + return B_ERROR; + } + rn->outputlist.MakeEmpty(); + for (int32 i = 0; i < count; i++) + rn->outputlist.Insert(outputs[i]); return B_OK; } @@ -75,20 +225,68 @@ NodeManager::PublishOutputs(const media_node &node, const media_output *outputs, status_t NodeManager::FindNodeId(media_node_id *nodeid, port_id port) { - return B_OK; + registered_node *rn; + for (int32 i = 0; fRegisteredNodeMap->GetPointerAt(i, &rn); i++) { + if (rn->port == port) { + *nodeid = rn->nodeid; + TRACE("NodeManager::FindNodeId found port %ld, node %ld\n", port, *nodeid); + return B_OK; + } + media_output *output; + for (int32 j = 0; rn->outputlist.GetPointerAt(j, &output); j++) { + if (output->source.port == port || output->destination.port == port) { + *nodeid = rn->nodeid; + TRACE("NodeManager::FindNodeId found output port %ld, node %ld\n", port, *nodeid); + return B_OK; + } + } + media_input *input; + for (int32 j = 0; rn->inputlist.GetPointerAt(j, &input); j++) { + if (input->source.port == port || input->destination.port == port) { + *nodeid = rn->nodeid; + TRACE("NodeManager::FindNodeId found input port %ld, node %ld\n", port, *nodeid); + return B_OK; + } + } + } + TRACE("!!! NodeManager::FindNodeId failed, port %ld\n", port); + return B_ERROR; } status_t NodeManager::GetLiveNodeInfo(live_node_info *live_info, const media_node &node) { - return B_OK; + registered_node *rn; + for (int32 i = 0; fRegisteredNodeMap->GetPointerAt(i, &rn); i++) { + if (rn->nodeid == node.node) { + ASSERT(node.port == rn->port); + ASSERT(node.kind == rn->kinds); + live_info->node = node; + live_info->hint_point = BPoint(0, 0); + strcpy(live_info->name, rn->name); + TRACE("NodeManager::GetLiveNodeInfo node %ld, name = '%s'\n", node.node, rn->name); + return B_OK; + } + } + TRACE("!!! NodeManager::GetLiveNodeInfo failed, node %ld\n", node.node); + return B_ERROR; } status_t NodeManager::GetInstances(media_node_id *node_ids, int32* count, int32 maxcount, media_addon_id addon_id, int32 addon_flavor_id) { + registered_node *rn; + *count = 0; + for (int32 i = 0; (maxcount > 0) && fRegisteredNodeMap->GetPointerAt(i, &rn); i++) { + if (rn->addon_id == addon_id && rn->addon_flavor_id == addon_flavor_id) { + node_ids[*count] = rn->nodeid; + *count += 1; + maxcount -= 1; + } + } + TRACE("NodeManager::GetInstances found %ld instances for addon_id %ld, addon_flavor_id %ld\n", *count, addon_id, addon_flavor_id); return B_OK; } @@ -96,6 +294,62 @@ NodeManager::GetInstances(media_node_id *node_ids, int32* count, int32 maxcount, status_t NodeManager::GetLiveNodes(Stack *livenodes, int32 maxcount, const media_format *inputformat /* = NULL */, const media_format *outputformat /* = NULL */, const char* name /* = NULL */, uint64 require_kinds /* = 0 */) { + registered_node *rn; + int namelen; + + // determine the count of byte to compare when checking for a name with(out) wildcard + if (name) { + namelen = strlen(name); + if (name[namelen] == '*') + namelen--; // compares without the '*' + else + namelen++; // also compares the terminating NULL + } else + namelen = 0; + + for (int32 index = 0; (maxcount > 0) && fRegisteredNodeMap->GetPointerAt(index, &rn); index++) { + if ((rn->kinds & require_kinds) != require_kinds) + continue; + if (namelen) { + if (0 != memcmp(name, rn->name, namelen)) + continue; + } + if (inputformat) { + bool hasit = false; + media_input *input; + for (int32 j = 0; rn->inputlist.GetPointerAt(j, &input); j++) { + if (format_is_compatible(*inputformat, input->format)) { + hasit = true; + break; + } + } + if (!hasit) + continue; + } + if (outputformat) { + bool hasit = false; + media_output *output; + for (int32 j = 0; rn->outputlist.GetPointerAt(j, &output); j++) { + if (format_is_compatible(*outputformat, output->format)) { + hasit = true; + break; + } + } + if (!hasit) + continue; + } + + live_node_info lni; + lni.node.node = rn->nodeid; + lni.node.port = rn->port; + lni.node.kind = rn->kinds; + lni.hint_point = BPoint(0, 0); + strcpy(lni.name, rn->name); + livenodes->Push(lni); + maxcount -= 1; + } + + TRACE("NodeManager::GetLiveNodes found %ld\n", livenodes->CountItems()); return B_OK; } @@ -103,7 +357,21 @@ NodeManager::GetLiveNodes(Stack *livenodes, int32 maxcount, cons status_t NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node &node) { - return B_OK; + // XXX not sure if this is correct + registered_node *rn; + for (int32 i = 0; fRegisteredNodeMap->GetPointerAt(i, &rn); i++) { + if (rn->nodeid == node.node) { + ASSERT(node.port == rn->port); + ASSERT(node.kind == rn->kinds); + node_info->addon = rn->addon_id; + node_info->flavor_id = rn->addon_flavor_id; + strcpy(node_info->name, rn->name); + TRACE("NodeManager::GetDormantNodeInfo node %ld, addon_id %ld, addon_flavor_id %ld, name '%s'\n", node.node, rn->addon_id, rn->addon_flavor_id, rn->name); + return B_OK; + } + } + TRACE("!!! NodeManager::GetDormantNodeInfo failed, node %ld\n", node.node); + return B_ERROR; } @@ -113,9 +381,9 @@ NodeManager::GetDormantNodeInfo(dormant_node_info *node_info, const media_node & status_t NodeManager::GetLiveNodes(BMessage *msg) { - msg->AddInt32("media_node_id", 1); - msg->AddInt32("media_node_id", 2); - msg->AddInt32("media_node_id", 3); + registered_node *rn; + for (int32 i = 0; fRegisteredNodeMap->GetPointerAt(i, &rn); i++) + msg->AddInt32("media_node_id", rn->nodeid); return B_OK; } diff --git a/src/servers/media/NodeManager.h b/src/servers/media/NodeManager.h index 5d1490aace..dc868e6489 100644 --- a/src/servers/media/NodeManager.h +++ b/src/servers/media/NodeManager.h @@ -1,8 +1,27 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include "TList.h" #include "TMap.h" #include "TStack.h" #include "DataExchange.h" +struct registered_node +{ + media_node_id nodeid; + media_addon_id addon_id; + int32 addon_flavor_id; + char name[B_MEDIA_NAME_LENGTH]; + uint64 kinds; + port_id port; + team_id team; + int32 globalrefcount; + Map teamrefcount; + List inputlist; + List outputlist; +}; + class BufferManager; class NodeManager @@ -21,9 +40,7 @@ public: status_t FindNodesFor(long, long, BMessage &, char const *); status_t FindNodesForPort(long, BMessage &, char const *); status_t UnregisterTeamNodes(long, BMessage &, char const *, long *, BufferManager *); - status_t IncrementGlobalRefCount(long); status_t DumpGlobalReferences(BMessage &, char const *); - status_t DecrementGlobalRefCount(long, BMessage *); status_t BroadcastMessage(long, void *, long, long long); status_t LoadState(); status_t SaveState(); @@ -41,6 +58,8 @@ public: status_t GetInstances(media_node_id *node_ids, int32* count, int32 maxcount, media_addon_id addon_id, int32 addon_flavor_id); status_t GetLiveNodes(Stack *livenodes, int32 maxcount, const media_format *inputformat = NULL, const media_format *outputformat = NULL, const char* name = NULL, uint64 require_kinds = 0); status_t GetDormantNodeInfo(dormant_node_info *node_info, const media_node &node); + status_t IncrementGlobalRefCount(media_node_id nodeid, team_id team); + status_t DecrementGlobalRefCount(media_node_id nodeid, team_id team); /* Add media_node_id of all live nodes to the message * int32 "media_node_id" (multiple items) @@ -66,7 +85,9 @@ public: private: media_addon_id nextaddonid; + media_node_id nextnodeid; List *fDormantFlavorList; Map *fAddonPathMap; + Map *fRegisteredNodeMap; }; diff --git a/src/servers/media/NotificationManager.cpp b/src/servers/media/NotificationManager.cpp index 45120a5f19..25ff86c942 100644 --- a/src/servers/media/NotificationManager.cpp +++ b/src/servers/media/NotificationManager.cpp @@ -1,9 +1,14 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include #include #include #include #include #include +#include "debug.h" #include "NodeManager.h" #include "DataExchange.h" #include "Notifications.h" @@ -64,6 +69,8 @@ NotificationManager::RequestNotifications(BMessage *msg) n.node = *node; n.what = what; n.team = team; + + TRACE("NotificationManager::RequestNotifications node %ld, team %ld, what %#lx\n",node->node, team, what); fLocker->Lock(); fNotificationList->Insert(n); @@ -90,6 +97,8 @@ NotificationManager::CancelNotifications(BMessage *msg) msg->FindInt32(NOTIFICATION_PARAM_WHAT, &what); msg->FindData("node", B_RAW_TYPE, reinterpret_cast(&node), &nodesize); ASSERT(nodesize == sizeof(media_node)); + + TRACE("NotificationManager::CancelNotifications node %ld, team %ld, what %#lx\n",node->node, team, what); /* if what == B_MEDIA_WILDCARD && node == media_node::null * => delete all notifications for the matching team & messenger @@ -141,6 +150,8 @@ NotificationManager::SendNotifications(BMessage *msg) msg->RemoveName(NOTIFICATION_PARAM_WHAT); msg->what = what; + TRACE("NotificationManager::SendNotifications what %#lx\n", what); + fLocker->Lock(); Notification n; @@ -182,6 +193,7 @@ NotificationManager::SendNotifications(BMessage *msg) break; } + TRACE("NotificationManager::SendNotifications sending\n"); n.messenger.SendMessage(msg, static_cast(NULL), TIMEOUT); } @@ -191,6 +203,7 @@ NotificationManager::SendNotifications(BMessage *msg) void NotificationManager::CleanupTeam(team_id team) { + TRACE("NotificationManager::CleanupTeam team %ld\n", team); fLocker->Lock(); Notification n; diff --git a/src/servers/media/NotificationManager.h b/src/servers/media/NotificationManager.h index 2339de5cb3..a96a3a9f62 100644 --- a/src/servers/media/NotificationManager.h +++ b/src/servers/media/NotificationManager.h @@ -1,3 +1,7 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include #include "TList.h" diff --git a/src/servers/media/Queue.cpp b/src/servers/media/Queue.cpp index f01fd400f7..47a6dfc277 100644 --- a/src/servers/media/Queue.cpp +++ b/src/servers/media/Queue.cpp @@ -59,7 +59,7 @@ Queue::AddItem(void *item) if (fSem < 0) { rv = B_ERROR; } else { - if (B_OK == fList->AddItem(item)) { + if (fList->AddItem(item)) { // AddItem returns a bool release_sem(fSem); rv = B_OK; } else {