more BMediaRoster functionality
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1381 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -71,15 +71,24 @@ enum {
|
||||
SERVER_SET_NODE,
|
||||
SERVER_PUBLISH_INPUTS,
|
||||
SERVER_PUBLISH_OUTPUTS,
|
||||
SERVER_NODE_ID_FOR,
|
||||
SERVER_GET_LIVE_NODE_INFO,
|
||||
SERVER_GET_LIVE_NODES,
|
||||
SERVER_GET_NODE_FOR,
|
||||
SERVER_RELEASE_NODE,
|
||||
SERVER_REGISTER_NODE,
|
||||
SERVER_UNREGISTER_NODE,
|
||||
CONSUMER_GET_NEXT_INPUT = 0x2000,
|
||||
CONSUMER_DISPOSE_INPUT_COOKIE,
|
||||
CONSUMER_ACCEPT_FORMAT,
|
||||
CONSUMER_CONNECTED,
|
||||
CONSUMER_DISCONNECTED,
|
||||
PRODUCER_GET_NEXT_OUTPUT = 0x3000,
|
||||
PRODUCER_DISPOSE_OUTPUT_COOKIE,
|
||||
PRODUCER_FORMAT_PROPOSAL,
|
||||
PRODUCER_PREPARE_TO_CONNECT,
|
||||
PRODUCER_CONNECT,
|
||||
PRODUCER_DISCONNECT,
|
||||
};
|
||||
|
||||
// used by SERVER_GET_NODE and SERVER_SET_NODE
|
||||
@@ -102,6 +111,12 @@ enum
|
||||
MAX_INPUTS = 48,
|
||||
};
|
||||
|
||||
// used by SERVER_GET_LIVE_NODES
|
||||
enum
|
||||
{
|
||||
MAX_LIVE_INFO = 62,
|
||||
};
|
||||
|
||||
struct addonserver_instantiate_dormant_node_request : public request_data
|
||||
{
|
||||
dormant_node_info info;
|
||||
@@ -130,6 +145,7 @@ struct server_set_node_reply : public reply_data
|
||||
struct server_get_node_request : public request_data
|
||||
{
|
||||
node_type type;
|
||||
team_id team;
|
||||
};
|
||||
|
||||
struct server_get_node_reply : public reply_data
|
||||
@@ -208,7 +224,9 @@ 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_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
|
||||
media_input inputs[MAX_INPUTS];
|
||||
};
|
||||
|
||||
@@ -268,4 +286,112 @@ struct consumer_dispose_input_cookie_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
struct consumer_disconnected_request : public request_data
|
||||
{
|
||||
media_source source;
|
||||
media_destination destination;
|
||||
};
|
||||
|
||||
struct consumer_disconnected_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
struct producer_disconnect_request : public request_data
|
||||
{
|
||||
media_source source;
|
||||
media_destination destination;
|
||||
};
|
||||
|
||||
struct producer_disconnect_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
struct server_register_node_request : public request_data
|
||||
{
|
||||
media_addon_id addon_id;
|
||||
int32 addon_flavor_id;
|
||||
char name[B_MEDIA_NAME_LENGTH];
|
||||
uint64 kinds;
|
||||
port_id port;
|
||||
team_id team;
|
||||
};
|
||||
|
||||
struct server_register_node_reply : public reply_data
|
||||
{
|
||||
media_node_id nodeid;
|
||||
};
|
||||
|
||||
struct server_unregister_node_request : public request_data
|
||||
{
|
||||
media_node_id nodeid;
|
||||
team_id team;
|
||||
};
|
||||
|
||||
struct server_unregister_node_reply : public reply_data
|
||||
{
|
||||
media_addon_id addon_id;
|
||||
};
|
||||
|
||||
struct server_get_live_node_info_request : public request_data
|
||||
{
|
||||
media_node node;
|
||||
};
|
||||
|
||||
struct server_get_live_node_info_reply : public reply_data
|
||||
{
|
||||
live_node_info live_info;
|
||||
};
|
||||
|
||||
struct server_get_live_nodes_request : public request_data
|
||||
{
|
||||
int32 maxcount;
|
||||
bool has_input;
|
||||
bool has_output;
|
||||
bool has_name;
|
||||
media_format inputformat;
|
||||
media_format outputformat;
|
||||
char name[B_MEDIA_NAME_LENGTH + 1]; // 1 for a trailing "*"
|
||||
uint64 require_kinds;
|
||||
};
|
||||
|
||||
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
|
||||
live_node_info live_info[MAX_LIVE_INFO];
|
||||
};
|
||||
|
||||
struct server_node_id_for_request : public request_data
|
||||
{
|
||||
port_id port;
|
||||
};
|
||||
|
||||
struct server_node_id_for_reply : public reply_data
|
||||
{
|
||||
media_node_id nodeid;
|
||||
};
|
||||
|
||||
struct server_get_node_for_request : public request_data
|
||||
{
|
||||
media_node_id nodeid;
|
||||
team_id team;
|
||||
};
|
||||
|
||||
struct server_get_node_for_reply : public reply_data
|
||||
{
|
||||
media_node clone;
|
||||
};
|
||||
|
||||
struct server_release_node_request : public request_data
|
||||
{
|
||||
media_node node;
|
||||
team_id team;
|
||||
};
|
||||
|
||||
struct server_release_node_reply : public reply_data
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
#endif // _DATA_EXCHANGE_H
|
||||
|
||||
@@ -395,8 +395,10 @@ BBufferConsumer::HandleMessage(int32 message,
|
||||
|
||||
case CONSUMER_DISCONNECTED:
|
||||
{
|
||||
const xfer_consumer_disconnected *request = (const xfer_consumer_disconnected *)rawdata;
|
||||
Disconnected(request->producer, request->where);
|
||||
const consumer_disconnected_request *request = (const consumer_disconnected_request *)rawdata;
|
||||
consumer_disconnected_reply reply;
|
||||
Disconnected(request->source, request->destination);
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,8 +149,10 @@ BBufferProducer::HandleMessage(int32 message,
|
||||
|
||||
case PRODUCER_DISCONNECT:
|
||||
{
|
||||
const xfer_producer_disconnect *request = (const xfer_producer_disconnect *)rawdata;
|
||||
const producer_disconnect_request *request = (const producer_disconnect_request *)rawdata;
|
||||
producer_disconnect_reply reply;
|
||||
Disconnect(request->source, request->destination);
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -277,7 +277,7 @@ extern "C" void __10BMediaNodePCclUl(BMediaNode *self, const char *name, media_n
|
||||
BMediaNode::BMediaNode(const char *name)
|
||||
{
|
||||
CALLED();
|
||||
__10BMediaNodePCclUl(this,name,0,0);
|
||||
__10BMediaNodePCclUl(this,name,-1,0);
|
||||
}
|
||||
|
||||
|
||||
@@ -415,44 +415,44 @@ BMediaNode::SetTimeSource(BTimeSource *time_source)
|
||||
|
||||
/* virtual */ status_t
|
||||
BMediaNode::HandleMessage(int32 message,
|
||||
const void *rawdata,
|
||||
const void *data,
|
||||
size_t size)
|
||||
{
|
||||
CALLED();
|
||||
switch (message) {
|
||||
case NODE_START:
|
||||
{
|
||||
const xfer_node_start *data = (const xfer_node_start *)rawdata;
|
||||
Start(data->performance_time);
|
||||
const xfer_node_start *request = (const xfer_node_start *)data;
|
||||
Start(request->performance_time);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case NODE_STOP:
|
||||
{
|
||||
const xfer_node_stop *data = (const xfer_node_stop *)rawdata;
|
||||
Stop(data->performance_time, data->immediate);
|
||||
const xfer_node_stop *request = (const xfer_node_stop *)data;
|
||||
Stop(request->performance_time, request->immediate);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case NODE_SEEK:
|
||||
{
|
||||
const xfer_node_seek *data = (const xfer_node_seek *)rawdata;
|
||||
Seek(data->media_time, data->performance_time);
|
||||
const xfer_node_seek *request = (const xfer_node_seek *)data;
|
||||
Seek(request->media_time, request->performance_time);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case NODE_SET_RUN_MODE:
|
||||
{
|
||||
const xfer_node_set_run_mode *data = (const xfer_node_set_run_mode *)rawdata;
|
||||
fRunMode = data->mode;
|
||||
const xfer_node_set_run_mode *request = (const xfer_node_set_run_mode *)data;
|
||||
fRunMode = request->mode;
|
||||
SetRunMode(fRunMode);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case NODE_TIME_WARP:
|
||||
{
|
||||
const xfer_node_time_warp *data = (const xfer_node_time_warp *)rawdata;
|
||||
TimeWarp(data->at_real_time,data->to_performance_time);
|
||||
const xfer_node_time_warp *request = (const xfer_node_time_warp *)data;
|
||||
TimeWarp(request->at_real_time,request->to_performance_time);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -461,22 +461,14 @@ BMediaNode::HandleMessage(int32 message,
|
||||
Preroll();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case NODE_REGISTERED:
|
||||
{
|
||||
const xfer_node_registered *data = (const xfer_node_registered *)rawdata;
|
||||
fNodeID = data->node_id;
|
||||
NodeRegistered();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case NODE_SET_TIMESOURCE:
|
||||
{
|
||||
const xfer_node_set_timesource *data = (const xfer_node_set_timesource *)rawdata;
|
||||
const xfer_node_set_timesource *request = (const xfer_node_set_timesource *)data;
|
||||
bool first = (fTimeSourceID == 0);
|
||||
if (fTimeSource)
|
||||
fTimeSource->Release();
|
||||
fTimeSourceID = data->timesource_id;
|
||||
fTimeSourceID = request->timesource_id;
|
||||
fTimeSource = 0; // XXX create timesource object here
|
||||
fTimeSource = new _SysTimeSource;
|
||||
if (!first)
|
||||
@@ -486,8 +478,8 @@ BMediaNode::HandleMessage(int32 message,
|
||||
|
||||
case NODE_REQUEST_COMPLETED:
|
||||
{
|
||||
const xfer_node_request_completed *data = (const xfer_node_request_completed *)rawdata;
|
||||
RequestCompleted(data->info);
|
||||
const xfer_node_request_completed *request = (const xfer_node_request_completed *)data;
|
||||
RequestCompleted(request->info);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
+287
-43
@@ -13,6 +13,7 @@
|
||||
#include <TimeSource.h>
|
||||
#undef DEBUG
|
||||
#define DEBUG 3
|
||||
#include <Debug.h>
|
||||
#include "debug.h"
|
||||
#include "TStack.h"
|
||||
#include "PortPool.h"
|
||||
@@ -58,6 +59,7 @@ GetNode(node_type type, media_node * out_node, int32 * out_input_id, BString * o
|
||||
status_t rv;
|
||||
|
||||
request.type = type;
|
||||
request.team = team;
|
||||
rv = QueryServer(SERVER_GET_NODE, &request, sizeof(request), &reply, sizeof(reply));
|
||||
if (rv != B_OK)
|
||||
return rv;
|
||||
@@ -380,8 +382,25 @@ status_t
|
||||
BMediaRoster::GetNodeFor(media_node_id node,
|
||||
media_node * clone)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return B_ERROR;
|
||||
CALLED();
|
||||
if (clone == NULL)
|
||||
return B_BAD_VALUE;
|
||||
if (node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
server_get_node_for_request request;
|
||||
server_get_node_for_reply reply;
|
||||
status_t rv;
|
||||
|
||||
request.nodeid = node;
|
||||
request.team = team;
|
||||
|
||||
rv = QueryServer(SERVER_GET_NODE_FOR, &request, sizeof(request), &reply, sizeof(reply));
|
||||
if (rv != B_OK)
|
||||
return rv;
|
||||
|
||||
*clone = reply.clone;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -396,10 +415,18 @@ BMediaRoster::GetSystemTimeSource(media_node * clone)
|
||||
status_t
|
||||
BMediaRoster::ReleaseNode(const media_node & node)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return B_ERROR;
|
||||
}
|
||||
CALLED();
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
server_release_node_request request;
|
||||
server_release_node_reply reply;
|
||||
|
||||
request.node = node;
|
||||
request.team = team;
|
||||
|
||||
return QueryServer(SERVER_RELEASE_NODE, &request, sizeof(request), &reply, sizeof(reply));
|
||||
}
|
||||
|
||||
|
||||
BTimeSource *
|
||||
@@ -433,10 +460,14 @@ BMediaRoster::Connect(const media_source & from,
|
||||
CALLED();
|
||||
if (io_format == NULL || out_output == NULL || out_input == NULL)
|
||||
return B_BAD_VALUE;
|
||||
if (from == media_source::null)
|
||||
if (from == media_source::null) {
|
||||
TRACE("BMediaRoster::Connect: media_source invalid\n");
|
||||
return B_MEDIA_BAD_SOURCE;
|
||||
if (to == media_destination::null)
|
||||
}
|
||||
if (to == media_destination::null) {
|
||||
TRACE("BMediaRoster::Connect: media_destination invalid\n");
|
||||
return B_MEDIA_BAD_DESTINATION;
|
||||
}
|
||||
|
||||
status_t rv;
|
||||
producer_format_proposal_request request1;
|
||||
@@ -537,23 +568,89 @@ BMediaRoster::Connect(const media_source & from,
|
||||
|
||||
|
||||
// XXX register connection with server
|
||||
// XXX we should just send a notification, instead of republishing all endpoints
|
||||
Stack<media_output> outstack;
|
||||
Stack<media_input> instack;
|
||||
if (B_OK == GetAllOutputs(out_output->node , &outstack))
|
||||
PublishOutputs(out_output->node , &outstack);
|
||||
if (B_OK == GetAllInputs(out_input->node , &instack))
|
||||
PublishInputs(out_input->node, &instack);
|
||||
|
||||
|
||||
// XXX if (mute) BBufferProducer::EnableOutput(false)
|
||||
if (in_flags & B_CONNECT_MUTED) {
|
||||
}
|
||||
|
||||
|
||||
// send a notification
|
||||
BPrivate::media::notifications::ConnectionMade(*out_input, *out_output, *io_format);
|
||||
|
||||
return B_OK;
|
||||
};
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRoster::Disconnect(media_node_id source_node,
|
||||
BMediaRoster::Disconnect(media_node_id source_nodeid,
|
||||
const media_source & source,
|
||||
media_node_id destination_node,
|
||||
media_node_id destination_nodeid,
|
||||
const media_destination & destination)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return B_ERROR;
|
||||
CALLED();
|
||||
if (source_nodeid <= 0) {
|
||||
TRACE("BMediaRoster::Disconnect: source media_node_id invalid\n");
|
||||
return B_MEDIA_BAD_SOURCE;
|
||||
}
|
||||
if (destination_nodeid <= 0) {
|
||||
TRACE("BMediaRoster::Disconnect: source media_node_id invalid\n");
|
||||
return B_MEDIA_BAD_DESTINATION;
|
||||
}
|
||||
if (source == media_source::null) {
|
||||
TRACE("BMediaRoster::Disconnect: media_source invalid\n");
|
||||
return B_MEDIA_BAD_SOURCE;
|
||||
}
|
||||
if (destination == media_destination::null) {
|
||||
TRACE("BMediaRoster::Disconnect: media_destination invalid\n");
|
||||
return B_MEDIA_BAD_DESTINATION;
|
||||
}
|
||||
|
||||
producer_disconnect_request request2;
|
||||
producer_disconnect_reply reply2;
|
||||
consumer_disconnected_request request1;
|
||||
consumer_disconnected_reply reply1;
|
||||
status_t rv1, rv2;
|
||||
|
||||
// XXX we should ask the server if this connection really exists
|
||||
|
||||
request1.source = source;
|
||||
request1.destination = destination;
|
||||
request2.source = source;
|
||||
request2.destination = destination;
|
||||
|
||||
rv1 = QueryPort(source.port, PRODUCER_DISCONNECT, &request1, sizeof(request1), &reply1, sizeof(reply1));
|
||||
rv2 = QueryPort(destination.port, CONSUMER_DISCONNECTED, &request2, sizeof(request2), &reply2, sizeof(reply2));
|
||||
|
||||
// XXX unregister connection with server
|
||||
// XXX we should just send a notification, instead of republishing all endpoints
|
||||
Stack<media_output> outstack;
|
||||
Stack<media_input> instack;
|
||||
media_node sourcenode;
|
||||
media_node destnode;
|
||||
if (B_OK == GetNodeFor(source_nodeid, &sourcenode)) {
|
||||
if (B_OK == GetAllOutputs(sourcenode , &outstack))
|
||||
PublishOutputs(sourcenode , &outstack);
|
||||
ReleaseNode(sourcenode);
|
||||
} else TRACE("BMediaRoster::Disconnect: source GetNodeFor failed\n");
|
||||
if (B_OK == GetNodeFor(destination_nodeid, &destnode)) {
|
||||
if (B_OK == GetAllInputs(destnode , &instack))
|
||||
PublishInputs(destnode, &instack);
|
||||
ReleaseNode(destnode);
|
||||
} else TRACE("BMediaRoster::Disconnect: dest GetNodeFor failed\n");
|
||||
|
||||
|
||||
// send a notification
|
||||
BPrivate::media::notifications::ConnectionBroken(source, destination);
|
||||
|
||||
return (rv1 != B_OK || rv2 != B_OK) ? B_ERROR : B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -562,7 +659,7 @@ BMediaRoster::StartNode(const media_node & node,
|
||||
bigtime_t at_performance_time)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0)
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
xfer_node_start msg;
|
||||
@@ -578,7 +675,7 @@ BMediaRoster::StopNode(const media_node & node,
|
||||
bool immediate)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0)
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
xfer_node_stop msg;
|
||||
@@ -595,7 +692,7 @@ BMediaRoster::SeekNode(const media_node & node,
|
||||
bigtime_t at_performance_time)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0)
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
xfer_node_seek msg;
|
||||
@@ -611,7 +708,7 @@ BMediaRoster::StartTimeSource(const media_node & node,
|
||||
bigtime_t at_real_time)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0)
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
if ((node.kind & B_TIME_SOURCE) == 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
@@ -630,7 +727,7 @@ BMediaRoster::StopTimeSource(const media_node & node,
|
||||
bool immediate)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0)
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
if ((node.kind & B_TIME_SOURCE) == 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
@@ -649,7 +746,7 @@ BMediaRoster::SeekTimeSource(const media_node & node,
|
||||
bigtime_t at_real_time)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0)
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
if ((node.kind & B_TIME_SOURCE) == 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
@@ -678,7 +775,7 @@ BMediaRoster::SetRunModeNode(const media_node & node,
|
||||
BMediaNode::run_mode mode)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0)
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
xfer_node_set_run_mode msg;
|
||||
@@ -692,7 +789,7 @@ status_t
|
||||
BMediaRoster::PrerollNode(const media_node & node)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0)
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
char dummy;
|
||||
@@ -751,7 +848,6 @@ BMediaRoster::SetProducerRate(const media_node & producer,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Nodes will have available inputs/outputs as long as they are capable */
|
||||
/* of accepting more connections. The node may create an additional */
|
||||
/* output or input as the currently available is taken into usage. */
|
||||
@@ -759,8 +855,24 @@ status_t
|
||||
BMediaRoster::GetLiveNodeInfo(const media_node & node,
|
||||
live_node_info * out_live_info)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return B_ERROR;
|
||||
CALLED();
|
||||
if (out_live_info == NULL)
|
||||
return B_BAD_VALUE;
|
||||
if (node.node <= 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
|
||||
server_get_live_node_info_request request;
|
||||
server_get_live_node_info_reply reply;
|
||||
status_t rv;
|
||||
|
||||
request.node = node;
|
||||
|
||||
rv = QueryAddonServer(SERVER_GET_LIVE_NODE_INFO, &request, sizeof(request), &reply, sizeof(reply));
|
||||
if (rv != B_OK)
|
||||
return rv;
|
||||
|
||||
*out_live_info = reply.live_info;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -772,8 +884,65 @@ BMediaRoster::GetLiveNodes(live_node_info * out_live_nodes,
|
||||
const char * name,
|
||||
uint64 node_kinds)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return B_ERROR;
|
||||
CALLED();
|
||||
if (out_live_nodes == NULL || io_total_count == NULL)
|
||||
return B_BAD_VALUE;
|
||||
if (*io_total_count <= 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// XXX we also support the wildcard search as GetDormantNodes does. This needs to be documented
|
||||
|
||||
server_get_live_nodes_request request;
|
||||
server_get_live_nodes_reply reply;
|
||||
status_t rv;
|
||||
|
||||
request.maxcount = *io_total_count;
|
||||
request.has_input = (bool) has_input;
|
||||
if (has_input)
|
||||
request.inputformat = *has_input; // XXX we should not make a flat copy of media_format
|
||||
request.has_output = (bool) has_output;
|
||||
if (has_output)
|
||||
request.outputformat = *has_output; // XXX we should not make a flat copy of media_format
|
||||
request.has_name = (bool) name;
|
||||
if (name) {
|
||||
int len = strlen(name);
|
||||
len = min_c(len, (int)sizeof(request.name) - 1);
|
||||
memcpy(request.name, name, len);
|
||||
request.name[len] = 0;
|
||||
}
|
||||
request.require_kinds = node_kinds;
|
||||
|
||||
rv = QueryServer(SERVER_GET_LIVE_NODES, &request, sizeof(request), &reply, sizeof(reply));
|
||||
if (rv != B_OK) {
|
||||
TRACE("BMediaRoster::GetLiveNodes failed\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (reply.count > MAX_LIVE_INFO) {
|
||||
live_node_info *live_info;
|
||||
area_id clone;
|
||||
|
||||
clone = clone_area("live_node_info clone", reinterpret_cast<void **>(&live_info), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, reply.area);
|
||||
if (clone < B_OK) {
|
||||
TRACE("BMediaRoster::GetLiveNodes failed to clone area, %#lx\n", clone);
|
||||
delete_area(reply.area);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < reply.count; i++) {
|
||||
out_live_nodes[i] = live_info[i];
|
||||
}
|
||||
|
||||
delete_area(clone);
|
||||
delete_area(reply.area);
|
||||
} else {
|
||||
for (int32 i = 0; i < reply.count; i++) {
|
||||
out_live_nodes[i] = reply.live_info[i];
|
||||
}
|
||||
}
|
||||
*io_total_count = reply.count;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -785,7 +954,7 @@ BMediaRoster::GetFreeInputsFor(const media_node & node,
|
||||
media_type filter_type)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0 || (node.kind & B_BUFFER_CONSUMER) == 0)
|
||||
if (node.node <= 0 || (node.kind & B_BUFFER_CONSUMER) == 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
if (out_free_inputs == NULL || out_total_count == NULL)
|
||||
return B_BAD_VALUE;
|
||||
@@ -823,7 +992,7 @@ BMediaRoster::GetConnectedInputsFor(const media_node & node,
|
||||
int32 * out_total_count)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0 || (node.kind & B_BUFFER_CONSUMER) == 0)
|
||||
if (node.node <= 0 || (node.kind & B_BUFFER_CONSUMER) == 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
if (out_active_inputs == NULL || out_total_count == NULL)
|
||||
return B_BAD_VALUE;
|
||||
@@ -859,7 +1028,7 @@ BMediaRoster::GetAllInputsFor(const media_node & node,
|
||||
int32 * out_total_count)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0 || (node.kind & B_BUFFER_CONSUMER) == 0)
|
||||
if (node.node <= 0 || (node.kind & B_BUFFER_CONSUMER) == 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
if (out_inputs == NULL || out_total_count == NULL)
|
||||
return B_BAD_VALUE;
|
||||
@@ -894,7 +1063,7 @@ BMediaRoster::GetFreeOutputsFor(const media_node & node,
|
||||
media_type filter_type)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0 || (node.kind & B_BUFFER_PRODUCER) == 0)
|
||||
if (node.node <= 0 || (node.kind & B_BUFFER_PRODUCER) == 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
if (out_free_outputs == NULL || out_total_count == NULL)
|
||||
return B_BAD_VALUE;
|
||||
@@ -932,7 +1101,7 @@ BMediaRoster::GetConnectedOutputsFor(const media_node & node,
|
||||
int32 * out_total_count)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0 || (node.kind & B_BUFFER_PRODUCER) == 0)
|
||||
if (node.node <= 0 || (node.kind & B_BUFFER_PRODUCER) == 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
if (out_active_outputs == NULL || out_total_count == NULL)
|
||||
return B_BAD_VALUE;
|
||||
@@ -968,7 +1137,7 @@ BMediaRoster::GetAllOutputsFor(const media_node & node,
|
||||
int32 * out_total_count)
|
||||
{
|
||||
CALLED();
|
||||
if (node.node == 0 || (node.kind & B_BUFFER_PRODUCER) == 0)
|
||||
if (node.node <= 0 || (node.kind & B_BUFFER_PRODUCER) == 0)
|
||||
return B_MEDIA_BAD_NODE;
|
||||
if (out_outputs == NULL || out_total_count == NULL)
|
||||
return B_BAD_VALUE;
|
||||
@@ -1034,7 +1203,7 @@ BMediaRoster::StartWatching(const BMessenger & where,
|
||||
TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
if (node.node == 0) {
|
||||
if (node.node <= 0) {
|
||||
TRACE("BMediaRoster::StartWatching: node invalid!\n");
|
||||
return B_MEDIA_BAD_NODE;
|
||||
}
|
||||
@@ -1076,7 +1245,7 @@ BMediaRoster::StopWatching(const BMessenger & where,
|
||||
{
|
||||
CALLED();
|
||||
// messenger may already be invalid, so we don't check this
|
||||
if (node.node == 0) {
|
||||
if (node.node <= 0) {
|
||||
TRACE("BMediaRoster::StopWatching: node invalid!\n");
|
||||
return B_MEDIA_BAD_NODE;
|
||||
}
|
||||
@@ -1096,13 +1265,38 @@ BMediaRoster::RegisterNode(BMediaNode * node)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t rv;
|
||||
BMediaAddOn *addon;
|
||||
int32 addon_flavor_id;
|
||||
media_addon_id addon_id;
|
||||
|
||||
addon_flavor_id = 0;
|
||||
addon = node->AddOn(&addon_flavor_id);
|
||||
addon_id = addon ? addon->AddonID() : -1;
|
||||
|
||||
// XXX fix node registration
|
||||
xfer_node_registered msg;
|
||||
msg.node_id = 1;
|
||||
server_register_node_request request;
|
||||
server_register_node_reply reply;
|
||||
|
||||
rv = node->HandleMessage(NODE_REGISTERED,&msg,sizeof(msg));
|
||||
request.addon_id = addon_id;
|
||||
request.addon_flavor_id = addon_flavor_id;
|
||||
strcpy(request.name, node->Name());
|
||||
request.kinds = node->Kinds();
|
||||
request.port = node->ControlPort();
|
||||
request.team = team;
|
||||
|
||||
rv = QueryServer(SERVER_REGISTER_NODE, &request, sizeof(request), &reply, sizeof(reply));
|
||||
if (rv != B_OK) {
|
||||
TRACE("BMediaRoster::RegisterNode: failed to register node %s (error %#lx)\n", node->Name(), rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// we are a friend class of BMediaNode and initilize this member variable
|
||||
node->fNodeID = reply.nodeid;
|
||||
ASSERT(reply.nodeid == node->Node().node);
|
||||
ASSERT(reply.nodeid == node->ID());
|
||||
|
||||
// call the callback
|
||||
node->NodeRegistered();
|
||||
|
||||
// register existing inputs and outputs with the
|
||||
// media_server, this allows GetLiveNodes() to work
|
||||
// with created, but unconnected nodes.
|
||||
@@ -1116,15 +1310,48 @@ BMediaRoster::RegisterNode(BMediaNode * node)
|
||||
PublishInputs(node->Node(), &stack);
|
||||
}
|
||||
|
||||
return rv;
|
||||
TRACE("BMediaRoster::RegisterNode: registered node %s, id %ld, addon %ld, flavor %ld\n", node->Name(), node->ID(), addon_id, addon_flavor_id);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRoster::UnregisterNode(BMediaNode * node)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return B_ERROR;
|
||||
CALLED();
|
||||
if (node == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (node->fRefCount != 0) {
|
||||
TRACE("BMediaRoster::UnregisterNode: Warning node %s has local reference count of %ld\n", node->Name(), node->fRefCount);
|
||||
// no return here, we continue and unregister!
|
||||
}
|
||||
if (node->ID() == -2) {
|
||||
TRACE("BMediaRoster::UnregisterNode: Warning node %s already unregistered\n", node->Name());
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
server_unregister_node_request request;
|
||||
server_unregister_node_reply reply;
|
||||
status_t rv;
|
||||
|
||||
request.nodeid = node->ID();
|
||||
request.team = team;
|
||||
|
||||
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);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (reply.addon_id != -1)
|
||||
_DormantNodeManager->PutAddon(reply.addon_id);
|
||||
|
||||
// we are a friend class of BMediaNode and initilize this member variable
|
||||
node->fNodeID = -2;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1219,8 +1446,9 @@ BMediaRoster::GetDormantNodes(dormant_node_info * out_info,
|
||||
msg.outputformat = *has_output;; // XXX we should not make a flat copy of media_format
|
||||
msg.has_name = (bool) name;
|
||||
if (name) {
|
||||
int len = min_c(strlen(name),sizeof(msg.name) - 1);
|
||||
memcpy(msg.name,name,len);
|
||||
int len = strlen(name);
|
||||
len = min_c(len, (int)sizeof(msg.name) - 1);
|
||||
memcpy(msg.name, name, len);
|
||||
msg.name[len] = 0;
|
||||
}
|
||||
msg.require_kinds = require_kinds;
|
||||
@@ -1350,6 +1578,7 @@ BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info,
|
||||
// XXX we must remember in_info.addon and call
|
||||
// XXX _DormantNodeManager->PutAddon when the
|
||||
// XXX node is unregistered
|
||||
// should be handled by RegisterNode() and UnegisterNode() now
|
||||
|
||||
*out_node = node->Node();
|
||||
return B_OK;
|
||||
@@ -1574,8 +1803,21 @@ BMediaRoster::GetNodeAttributesFor(const media_node & node,
|
||||
media_node_id
|
||||
BMediaRoster::NodeIDFor(port_id source_or_destination_port)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
return B_ERROR;
|
||||
CALLED();
|
||||
|
||||
server_node_id_for_request request;
|
||||
server_node_id_for_reply reply;
|
||||
status_t rv;
|
||||
|
||||
request.port = source_or_destination_port;
|
||||
|
||||
rv = QueryServer(SERVER_NODE_ID_FOR, &request, sizeof(request), &reply, sizeof(reply));
|
||||
if (rv != B_OK) {
|
||||
TRACE("BMediaRoster::NodeIDFor: failed (error %#lx)\n", rv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return reply.nodeid;
|
||||
}
|
||||
|
||||
|
||||
@@ -1586,6 +1828,7 @@ BMediaRoster::GetInstancesFor(media_addon_id addon,
|
||||
int32 * io_count)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
// flavor
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -1687,6 +1930,7 @@ BMediaRoster::SetOutputBuffersFor(const media_source & output,
|
||||
bool will_reclaim )
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
debugger("BMediaRoster::SetOutputBuffersFor missing\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,13 +59,11 @@ enum {
|
||||
NODE_SET_RUN_MODE,
|
||||
NODE_TIME_WARP,
|
||||
NODE_PREROLL,
|
||||
NODE_REGISTERED,
|
||||
NODE_SET_TIMESOURCE,
|
||||
NODE_REQUEST_COMPLETED,
|
||||
CONSUMER_BUFFER_RECEIVED,
|
||||
CONSUMER_PRODUCER_DATA_STATUS,
|
||||
CONSUMER_GET_LATENCY_FOR,
|
||||
CONSUMER_DISCONNECTED,
|
||||
CONSUMER_FORMAT_CHANGED,
|
||||
CONSUMER_SEEK_TAG_REQUESTED,
|
||||
PRODUCER_LATE_NOTICE_RECEIVED,
|
||||
@@ -77,7 +75,6 @@ enum {
|
||||
PRODUCER_GET_LATENCY,
|
||||
PRODUCER_GET_INITIAL_LATENCY,
|
||||
PRODUCER_FORMAT_SUGGESTION_REQUESTED,
|
||||
PRODUCER_DISCONNECT,
|
||||
PRODUCER_SET_PLAY_RATE,
|
||||
PRODUCER_ENABLE_OUTPUT,
|
||||
ADDONSERVER_INSTANTIATE_DORMANT_NODE,
|
||||
@@ -213,12 +210,6 @@ struct xfer_producer_format_suggestion_requested_reply
|
||||
status_t result;
|
||||
};
|
||||
|
||||
struct xfer_producer_disconnect
|
||||
{
|
||||
media_source source;
|
||||
media_destination destination;
|
||||
};
|
||||
|
||||
struct xfer_producer_set_play_rate
|
||||
{
|
||||
int32 numer;
|
||||
@@ -349,11 +340,6 @@ struct xfer_node_time_warp
|
||||
bigtime_t to_performance_time;
|
||||
};
|
||||
|
||||
struct xfer_node_registered
|
||||
{
|
||||
media_node_id node_id;
|
||||
};
|
||||
|
||||
struct xfer_node_set_timesource
|
||||
{
|
||||
media_node_id timesource_id;
|
||||
@@ -385,13 +371,6 @@ struct xfer_consumer_get_latency_for_reply
|
||||
status_t result;
|
||||
};
|
||||
|
||||
|
||||
struct xfer_consumer_disconnected
|
||||
{
|
||||
media_source producer;
|
||||
media_destination where;
|
||||
};
|
||||
|
||||
struct xfer_consumer_format_changed
|
||||
{
|
||||
media_source producer;
|
||||
|
||||
@@ -157,6 +157,7 @@ void
|
||||
ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
{
|
||||
status_t rv;
|
||||
printf("ServerApp::HandleMessage %#lx\n", code);
|
||||
switch (code) {
|
||||
case SERVER_GET_MEDIAADDON_REF:
|
||||
{
|
||||
@@ -169,39 +170,103 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_NODE_ID_FOR:
|
||||
{
|
||||
const server_node_id_for_request *request = reinterpret_cast<const server_node_id_for_request *>(data);
|
||||
server_node_id_for_reply reply;
|
||||
// XXX do something here
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_GET_LIVE_NODE_INFO:
|
||||
{
|
||||
const server_get_live_node_info_request *request = reinterpret_cast<const server_get_live_node_info_request *>(data);
|
||||
server_get_live_node_info_reply reply;
|
||||
// XXX do something here
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_GET_LIVE_NODES:
|
||||
{
|
||||
const server_get_live_nodes_request *request = reinterpret_cast<const server_get_live_nodes_request *>(data);
|
||||
server_get_live_nodes_reply reply;
|
||||
// XXX do something here
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_GET_NODE_FOR:
|
||||
{
|
||||
const server_get_node_for_request *request = reinterpret_cast<const server_get_node_for_request *>(data);
|
||||
server_get_node_for_reply reply;
|
||||
// XXX do something here
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_RELEASE_NODE:
|
||||
{
|
||||
const server_release_node_request *request = reinterpret_cast<const server_release_node_request *>(data);
|
||||
server_release_node_reply reply;
|
||||
// XXX do something here
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_REGISTER_NODE:
|
||||
{
|
||||
const server_register_node_request *request = reinterpret_cast<const server_register_node_request *>(data);
|
||||
server_register_node_reply reply;
|
||||
reply.nodeid = 1234;
|
||||
// XXX do something here
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_UNREGISTER_NODE:
|
||||
{
|
||||
const server_unregister_node_request *request = reinterpret_cast<const server_unregister_node_request *>(data);
|
||||
server_unregister_node_reply reply;
|
||||
// XXX do something here
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_PUBLISH_INPUTS:
|
||||
{
|
||||
server_publish_inputs_request *request = (server_publish_inputs_request *)data;
|
||||
const server_publish_inputs_request *request = reinterpret_cast<const server_publish_inputs_request *>(data);
|
||||
server_publish_inputs_reply reply;
|
||||
// XXX do something here
|
||||
request->SendReply(B_ERROR, &reply, sizeof(reply));
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_PUBLISH_OUTPUTS:
|
||||
{
|
||||
server_publish_outputs_request *request = (server_publish_outputs_request *)data;
|
||||
const server_publish_outputs_request *request = reinterpret_cast<const server_publish_outputs_request *>(data);
|
||||
server_publish_outputs_reply reply;
|
||||
// XXX do something here
|
||||
request->SendReply(B_ERROR, &reply, sizeof(reply));
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_GET_NODE:
|
||||
{
|
||||
server_get_node_request *request = (server_get_node_request *)data;
|
||||
const server_get_node_request *request = reinterpret_cast<const server_get_node_request *>(data);
|
||||
server_get_node_reply reply;
|
||||
// XXX do something here
|
||||
request->SendReply(B_ERROR, &reply, sizeof(reply));
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_SET_NODE:
|
||||
{
|
||||
server_set_node_request *request = (server_set_node_request *)data;
|
||||
const server_set_node_request *request = reinterpret_cast<const server_set_node_request *>(data);
|
||||
server_set_node_reply reply;
|
||||
// XXX do something here
|
||||
request->SendReply(B_ERROR, &reply, sizeof(reply));
|
||||
request->SendReply(B_OK, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user