diff --git a/headers/private/media/DataExchange.h b/headers/private/media/DataExchange.h index 3a68017ad3..54ad94700d 100644 --- a/headers/private/media/DataExchange.h +++ b/headers/private/media/DataExchange.h @@ -69,8 +69,14 @@ enum { enum { SERVER_GET_NODE = 1000, SERVER_SET_NODE, + SERVER_PUBLISH_INPUTS, + SERVER_PUBLISH_OUTPUTS, + CONSUMER_GET_NEXT_INPUT, + CONSUMER_DISPOSE_INPUT_COOKIE, CONSUMER_ACCEPT_FORMAT, CONSUMER_CONNECTED, + PRODUCER_GET_NEXT_OUTPUT, + PRODUCER_DISPOSE_OUTPUT_COOKIE, PRODUCER_FORMAT_PROPOSAL, PRODUCER_PREPARE_TO_CONNECT, PRODUCER_CONNECT, @@ -89,6 +95,12 @@ enum node_type SYSTEM_TIME_SOURCE }; +// used by SERVER_PUBLISH_INPUTS and SERVER_PUBLISH_OUTPUTS +enum +{ + MAX_OUTPUTS = 48, + MAX_INPUTS = 48, +}; struct addonserver_instantiate_dormant_node_request : public request_data { @@ -192,4 +204,68 @@ struct consumer_connected_reply : public reply_data media_input input; }; +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 + media_input inputs[MAX_INPUTS]; +}; + +struct server_publish_inputs_reply : public reply_data +{ +}; + +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 + media_output outputs[MAX_OUTPUTS]; +}; + +struct server_publish_outputs_reply : public reply_data +{ +}; + +struct producer_get_next_output_request : public request_data +{ + int32 cookie; +}; + +struct producer_get_next_output_reply : public reply_data +{ + int32 cookie; + media_output output; +}; + +struct producer_dispose_output_cookie_request : public request_data +{ + int32 cookie; +}; + +struct producer_dispose_output_cookie_reply : public reply_data +{ +}; + +struct consumer_get_next_input_request : public request_data +{ + int32 cookie; +}; + +struct consumer_get_next_input_reply : public reply_data +{ + int32 cookie; + media_input input; +}; + +struct consumer_dispose_input_cookie_request : public request_data +{ + int32 cookie; +}; + +struct consumer_dispose_input_cookie_reply : public reply_data +{ +}; + #endif // _DATA_EXCHANGE_H diff --git a/src/kits/media/BufferConsumer.cpp b/src/kits/media/BufferConsumer.cpp index 4c9424b161..5443497ed3 100644 --- a/src/kits/media/BufferConsumer.cpp +++ b/src/kits/media/BufferConsumer.cpp @@ -341,18 +341,20 @@ BBufferConsumer::HandleMessage(int32 message, case CONSUMER_GET_NEXT_INPUT: { - const xfer_consumer_get_next_input *request = (const xfer_consumer_get_next_input *)rawdata; - xfer_consumer_get_next_input_reply reply; + const consumer_get_next_input_request *request = (const consumer_get_next_input_request *)rawdata; + consumer_get_next_input_reply reply; reply.cookie = request->cookie; - reply.result = GetNextInput(&reply.cookie, &reply.input); - write_port(request->reply_port, 0, &reply, sizeof(reply)); + rv = GetNextInput(&reply.cookie, &reply.input); + request->SendReply(rv, &reply, sizeof(reply)); return B_OK; } case CONSUMER_DISPOSE_INPUT_COOKIE: { - const xfer_consumer_dispose_input_cookie *request = (const xfer_consumer_dispose_input_cookie *)rawdata; + const consumer_dispose_input_cookie_request *request = (const consumer_dispose_input_cookie_request *)rawdata; + consumer_dispose_input_cookie_reply reply; DisposeInputCookie(request->cookie); + request->SendReply(B_OK, &reply, sizeof(reply)); return B_OK; } diff --git a/src/kits/media/BufferProducer.cpp b/src/kits/media/BufferProducer.cpp index ab918ed196..8246d44234 100644 --- a/src/kits/media/BufferProducer.cpp +++ b/src/kits/media/BufferProducer.cpp @@ -184,18 +184,20 @@ BBufferProducer::HandleMessage(int32 message, case PRODUCER_GET_NEXT_OUTPUT: { - const xfer_producer_get_next_output *request = (const xfer_producer_get_next_output *)rawdata; - xfer_producer_get_next_output_reply reply; + const producer_get_next_output_request *request = (const producer_get_next_output_request *)rawdata; + producer_get_next_output_reply reply; reply.cookie = request->cookie; - reply.result = GetNextOutput(&reply.cookie, &reply.output); - write_port(request->reply_port, 0, &reply, sizeof(reply)); + rv = GetNextOutput(&reply.cookie, &reply.output); + request->SendReply(rv, &reply, sizeof(reply)); return B_OK; } case PRODUCER_DISPOSE_OUTPUT_COOKIE: { - const xfer_producer_dispose_output_cookie *request = (const xfer_producer_dispose_output_cookie *)rawdata; + const producer_dispose_output_cookie_request *request = (const producer_dispose_output_cookie_request *)rawdata; + producer_dispose_output_cookie_reply reply; DisposeOutputCookie(request->cookie); + request->SendReply(B_OK, &reply, sizeof(reply)); return B_OK; } diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp index a6bc2b3453..f0f7970d82 100644 --- a/src/kits/media/MediaNode.cpp +++ b/src/kits/media/MediaNode.cpp @@ -13,6 +13,7 @@ #include #include "SystemTimeSource.h" #include "debug.h" +#include "DataExchange.h" #include "ServerInterface.h" #include "Notifications.h" @@ -501,6 +502,31 @@ BMediaNode::HandleBadMessage(int32 code, size_t size) { CALLED(); + + TRACE("BMediaNode::HandleBadMessage: code %#08lx, buffer %p, size %ld\n", code, buffer, size); + switch (code) { + default: + { + TRACE("BMediaNode::HandleBadMessage: unknown code!\n"); + break; + } + + /* 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; + } + } } diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp index 189164a47f..8a24738a48 100644 --- a/src/kits/media/MediaRoster.cpp +++ b/src/kits/media/MediaRoster.cpp @@ -14,17 +14,18 @@ #undef DEBUG #define DEBUG 3 #include "debug.h" +#include "TStack.h" #include "PortPool.h" #include "ServerInterface.h" #include "DataExchange.h" #include "DormantNodeManager.h" #include "Notifications.h" -using namespace BPrivate::media; - namespace BPrivate { namespace media { extern team_id team; -}; }; +} } // BPrivate::media + +using namespace BPrivate::media; // the BMediaRoster destructor is private, // but _DefaultDeleter is a friend class of @@ -37,14 +38,17 @@ public: _DefaultDeleter _deleter; -namespace MediaKitPrivate -{ - +namespace BPrivate { namespace media { namespace mediaroster { 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 GetAllOutputs(const media_node & node, Stack *stack); +status_t GetAllInputs(const media_node & node, Stack *stack); +status_t PublishOutputs(const media_node & node, Stack *stack); +status_t PublishInputs(const media_node & node, Stack *stack); -status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id, BString * out_input_name) +status_t +GetNode(node_type type, media_node * out_node, int32 * out_input_id, BString * out_input_name) { if (out_node == NULL) return B_BAD_VALUE; @@ -66,7 +70,8 @@ status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id, BS return rv; } -status_t SetNode(node_type type, const media_node *node, const dormant_node_info *info, const media_input *input) +status_t +SetNode(node_type type, const media_node *node, const dormant_node_info *info, const media_input *input) { server_set_node_request request; server_set_node_reply reply; @@ -85,7 +90,145 @@ status_t SetNode(node_type type, const media_node *node, const dormant_node_info return QueryServer(SERVER_SET_NODE, &request, sizeof(request), &reply, sizeof(reply)); } -}; +status_t +GetAllOutputs(const media_node & node, Stack *stack) +{ + int32 cookie; + status_t rv; + status_t result; + + result = B_OK; + cookie = 0; + for (;;) { + producer_get_next_output_request request; + producer_get_next_output_reply reply; + request.cookie = cookie; + rv = QueryServer(PRODUCER_GET_NEXT_OUTPUT, &request, sizeof(request), &reply, sizeof(reply)); + if (rv != B_OK) + break; + cookie = reply.cookie; + if (!stack->Push(reply.output)) { + TRACE("GetAllOutputs: stack->Push failed\n"); + result = B_ERROR; + } + } + + producer_dispose_output_cookie_request request; + producer_dispose_output_cookie_reply reply; + QueryServer(PRODUCER_DISPOSE_OUTPUT_COOKIE, &request, sizeof(request), &reply, sizeof(reply)); + + return result; +} + +status_t +GetAllInputs(const media_node & node, Stack *stack) +{ + int32 cookie; + status_t rv; + status_t result; + + result = B_OK; + cookie = 0; + for (;;) { + consumer_get_next_input_request request; + consumer_get_next_input_reply reply; + request.cookie = cookie; + rv = QueryServer(CONSUMER_GET_NEXT_INPUT, &request, sizeof(request), &reply, sizeof(reply)); + if (rv != B_OK) + break; + cookie = reply.cookie; + if (!stack->Push(reply.input)) { + TRACE("GetAllInputs: stack->Push failed\n"); + result = B_ERROR; + } + } + + consumer_dispose_input_cookie_request request; + consumer_dispose_input_cookie_reply reply; + QueryServer(CONSUMER_DISPOSE_INPUT_COOKIE, &request, sizeof(request), &reply, sizeof(reply)); + + return result; +} + +status_t +PublishOutputs(const media_node & node, Stack *stack) +{ + server_publish_outputs_request request; + server_publish_outputs_reply reply; + media_output *output; + media_output *outputs; + int32 count; + + count = stack->CountItems(); + TRACE("PublishOutputs: publishing %ld\n", count); + + request.node = node; + request.count = count; + if (count > MAX_OUTPUTS) { + void *start_addr; + size_t size; + size = ((count * sizeof(media_output)) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); + request.area = create_area("publish outputs", &start_addr, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); + if (request.area < B_OK) { + TRACE("PublishOutputs: failed to create area, %#lx\n", request.area); + return (status_t)request.area; + } + outputs = static_cast(start_addr); + } else { + request.area = -1; + outputs = request.outputs; + } + TRACE("PublishOutputs: area %#lx\n", request.area); + + for (int32 i = 0; i != count; i++) { + stack->GetPointerAt(i, &output); + outputs[i] = *output; + } + + return QueryServer(SERVER_PUBLISH_OUTPUTS, &request, sizeof(request), &reply, sizeof(reply)); +} + +status_t +PublishInputs(const media_node & node, Stack *stack) +{ + server_publish_inputs_request request; + server_publish_inputs_reply reply; + media_input *input; + media_input *inputs; + int32 count; + + count = stack->CountItems(); + TRACE("PublishInputs: publishing %ld\n", count); + + request.node = node; + request.count = count; + if (count > MAX_INPUTS) { + void *start_addr; + size_t size; + size = ((count * sizeof(media_input)) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); + request.area = create_area("publish inputs", &start_addr, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); + if (request.area < B_OK) { + TRACE("PublishInputs: failed to create area, %#lx\n", request.area); + return (status_t)request.area; + } + inputs = static_cast(start_addr); + } else { + request.area = -1; + inputs = request.inputs; + } + TRACE("PublishInputs: area %#lx\n", request.area); + + for (int32 i = 0; i != count; i++) { + stack->GetPointerAt(i, &input); + inputs[i] = *input; + } + + return QueryServer(SERVER_PUBLISH_INPUTS, &request, sizeof(request), &reply, sizeof(reply)); +} + +} } } // namespace BPrivate::media::mediaroster + +using namespace BPrivate::media::mediaroster; /************************************************************* * public BMediaRoster @@ -95,7 +238,7 @@ status_t BMediaRoster::GetVideoInput(media_node * out_node) { CALLED(); - return MediaKitPrivate::GetNode(VIDEO_INPUT, out_node); + return GetNode(VIDEO_INPUT, out_node); } @@ -103,7 +246,7 @@ status_t BMediaRoster::GetAudioInput(media_node * out_node) { CALLED(); - return MediaKitPrivate::GetNode(AUDIO_INPUT, out_node); + return GetNode(AUDIO_INPUT, out_node); } @@ -111,7 +254,7 @@ status_t BMediaRoster::GetVideoOutput(media_node * out_node) { CALLED(); - return MediaKitPrivate::GetNode(VIDEO_OUTPUT, out_node); + return GetNode(VIDEO_OUTPUT, out_node); } @@ -119,7 +262,7 @@ status_t BMediaRoster::GetAudioMixer(media_node * out_node) { CALLED(); - return MediaKitPrivate::GetNode(AUDIO_MIXER, out_node); + return GetNode(AUDIO_MIXER, out_node); } @@ -127,7 +270,7 @@ status_t BMediaRoster::GetAudioOutput(media_node * out_node) { CALLED(); - return MediaKitPrivate::GetNode(AUDIO_OUTPUT, out_node); + return GetNode(AUDIO_OUTPUT, out_node); } @@ -137,7 +280,7 @@ BMediaRoster::GetAudioOutput(media_node * out_node, BString * out_input_name) { CALLED(); - return MediaKitPrivate::GetNode(AUDIO_OUTPUT_EX, out_node, out_input_id, out_input_name); + return GetNode(AUDIO_OUTPUT_EX, out_node, out_input_id, out_input_name); } @@ -145,7 +288,7 @@ status_t BMediaRoster::GetTimeSource(media_node * out_node) { CALLED(); - return MediaKitPrivate::GetNode(TIME_SOURCE, out_node); + return GetNode(TIME_SOURCE, out_node); } @@ -153,7 +296,7 @@ status_t BMediaRoster::SetVideoInput(const media_node & producer) { CALLED(); - return MediaKitPrivate::SetNode(VIDEO_INPUT, &producer); + return SetNode(VIDEO_INPUT, &producer); } @@ -161,7 +304,7 @@ status_t BMediaRoster::SetVideoInput(const dormant_node_info & producer) { CALLED(); - return MediaKitPrivate::SetNode(VIDEO_INPUT, NULL, &producer); + return SetNode(VIDEO_INPUT, NULL, &producer); } @@ -169,7 +312,7 @@ status_t BMediaRoster::SetAudioInput(const media_node & producer) { CALLED(); - return MediaKitPrivate::SetNode(AUDIO_INPUT, &producer); + return SetNode(AUDIO_INPUT, &producer); } @@ -177,7 +320,7 @@ status_t BMediaRoster::SetAudioInput(const dormant_node_info & producer) { CALLED(); - return MediaKitPrivate::SetNode(AUDIO_INPUT, NULL, &producer); + return SetNode(AUDIO_INPUT, NULL, &producer); } @@ -185,7 +328,7 @@ status_t BMediaRoster::SetVideoOutput(const media_node & consumer) { CALLED(); - return MediaKitPrivate::SetNode(VIDEO_OUTPUT, &consumer); + return SetNode(VIDEO_OUTPUT, &consumer); } @@ -193,7 +336,7 @@ status_t BMediaRoster::SetVideoOutput(const dormant_node_info & consumer) { CALLED(); - return MediaKitPrivate::SetNode(VIDEO_OUTPUT, NULL, &consumer); + return SetNode(VIDEO_OUTPUT, NULL, &consumer); } @@ -201,7 +344,7 @@ status_t BMediaRoster::SetAudioOutput(const media_node & consumer) { CALLED(); - return MediaKitPrivate::SetNode(AUDIO_OUTPUT, &consumer); + return SetNode(AUDIO_OUTPUT, &consumer); } @@ -209,7 +352,7 @@ status_t BMediaRoster::SetAudioOutput(const media_input & input_to_output) { CALLED(); - return MediaKitPrivate::SetNode(AUDIO_OUTPUT, NULL, NULL, &input_to_output); + return SetNode(AUDIO_OUTPUT, NULL, NULL, &input_to_output); } @@ -217,7 +360,7 @@ status_t BMediaRoster::SetAudioOutput(const dormant_node_info & consumer) { CALLED(); - return MediaKitPrivate::SetNode(AUDIO_OUTPUT, NULL, &consumer); + return SetNode(AUDIO_OUTPUT, NULL, &consumer); } @@ -234,7 +377,7 @@ status_t BMediaRoster::GetSystemTimeSource(media_node * clone) { CALLED(); - return MediaKitPrivate::GetNode(SYSTEM_TIME_SOURCE, clone); + return GetNode(SYSTEM_TIME_SOURCE, clone); } @@ -629,22 +772,74 @@ BMediaRoster::GetFreeInputsFor(const media_node & node, int32 * out_total_count, media_type filter_type) { - UNIMPLEMENTED(); - return B_ERROR; + CALLED(); + if (node.node == 0 || (node.kind & B_BUFFER_PRODUCER) == 0) + return B_MEDIA_BAD_NODE; + if (out_free_inputs == NULL || out_total_count == NULL) + return B_BAD_VALUE; + + Stack stack; + media_input *input; + status_t rv; + + 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 + if (input->source != media_source::null) + continue; // consumer source already connected + out_free_inputs[i] = *input; + *out_total_count += 1; + buf_num_inputs -= 1; + if (buf_num_inputs == 0) + break; + } + + PublishInputs(node, &stack); + return B_OK; } - + status_t BMediaRoster::GetConnectedInputsFor(const media_node & node, media_input * out_active_inputs, int32 buf_num_inputs, int32 * out_total_count) { - UNIMPLEMENTED(); - return B_ERROR; + CALLED(); + if (node.node == 0 || (node.kind & B_BUFFER_PRODUCER) == 0) + return B_MEDIA_BAD_NODE; + if (out_active_inputs == NULL || out_total_count == NULL) + return B_BAD_VALUE; + + Stack stack; + media_input *input; + status_t rv; + + 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 + out_active_inputs[i] = *input; + *out_total_count += 1; + buf_num_inputs -= 1; + if (buf_num_inputs == 0) + break; + } + + PublishInputs(node, &stack); + return B_OK; } - + status_t BMediaRoster::GetAllInputsFor(const media_node & node, media_input * out_inputs, @@ -657,41 +852,28 @@ BMediaRoster::GetAllInputsFor(const media_node & node, if (out_inputs == NULL || out_total_count == NULL) return B_BAD_VALUE; + Stack stack; + media_input *input; status_t rv; - status_t rv2; - port_id port; - int32 code; - int32 cookie; - - port = _PortPool->GetPort(); - *out_total_count = 0; - cookie = 0; - rv = B_OK; - for (int32 i = 0; i < buf_num_inputs; i++) { - xfer_consumer_get_next_input msg; - xfer_consumer_get_next_input_reply reply; - msg.cookie = cookie; - msg.reply_port = port; - rv = write_port(node.port, CONSUMER_GET_NEXT_INPUT, &msg, sizeof(msg)); - if (rv != B_OK) - break; - rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); - if (rv < B_OK || reply.result != B_OK) - break; - *out_total_count += 1; - out_inputs[i] = reply.input; - cookie = reply.cookie; - } - _PortPool->PutPort(port); - - xfer_consumer_dispose_input_cookie msg2; - msg2.cookie = cookie; - rv2 = write_port(node.port, CONSUMER_DISPOSE_INPUT_COOKIE, &msg2, sizeof(msg2)); - return (rv < B_OK) ? rv : rv2; + 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; + buf_num_inputs -= 1; + if (buf_num_inputs == 0) + break; + } + + PublishInputs(node, &stack); + return B_OK; } - + status_t BMediaRoster::GetFreeOutputsFor(const media_node & node, media_output * out_free_outputs, @@ -699,8 +881,35 @@ BMediaRoster::GetFreeOutputsFor(const media_node & node, int32 * out_total_count, media_type filter_type) { - UNIMPLEMENTED(); - return B_ERROR; + CALLED(); + 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; + + Stack stack; + media_output *output; + status_t rv; + + 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 + if (output->destination != media_destination::null) + continue; // producer destination already connected + out_free_outputs[i] = *output; + *out_total_count += 1; + buf_num_outputs -= 1; + if (buf_num_outputs == 0) + break; + } + + PublishOutputs(node, &stack); + return B_OK; } @@ -710,8 +919,33 @@ BMediaRoster::GetConnectedOutputsFor(const media_node & node, int32 buf_num_outputs, int32 * out_total_count) { - UNIMPLEMENTED(); - return B_ERROR; + CALLED(); + 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; + + Stack stack; + media_output *output; + status_t rv; + + 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 + out_active_outputs[i] = *output; + *out_total_count += 1; + buf_num_outputs -= 1; + if (buf_num_outputs == 0) + break; + } + + PublishOutputs(node, &stack); + return B_OK; } @@ -726,39 +960,26 @@ BMediaRoster::GetAllOutputsFor(const media_node & node, return B_MEDIA_BAD_NODE; if (out_outputs == NULL || out_total_count == NULL) return B_BAD_VALUE; - - status_t rv; - status_t rv2; - port_id port; - int32 code; - int32 cookie; - port = _PortPool->GetPort(); - *out_total_count = 0; - cookie = 0; - rv = B_OK; - for (int32 i = 0; i < buf_num_outputs; i++) { - xfer_producer_get_next_output msg; - xfer_producer_get_next_output_reply reply; - msg.cookie = cookie; - msg.reply_port = port; - rv = write_port(node.port, PRODUCER_GET_NEXT_OUTPUT, &msg, sizeof(msg)); - if (rv != B_OK) - break; - rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); - if (rv < B_OK || reply.result != B_OK) - break; - *out_total_count += 1; - out_outputs[i] = reply.output; - cookie = reply.cookie; - } - _PortPool->PutPort(port); - - xfer_producer_dispose_output_cookie msg2; - msg2.cookie = cookie; - rv2 = write_port(node.port, PRODUCER_DISPOSE_OUTPUT_COOKIE, &msg2, sizeof(msg2)); + Stack stack; + media_output *output; + status_t rv; - return (rv < B_OK) ? rv : rv2; + 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; + buf_num_outputs -= 1; + if (buf_num_outputs == 0) + break; + } + + PublishOutputs(node, &stack); + return B_OK; } @@ -861,11 +1082,29 @@ BMediaRoster::RegisterNode(BMediaNode * node) CALLED(); if (node == NULL) return B_BAD_VALUE; + + status_t rv; + // XXX fix node registration xfer_node_registered msg; msg.node_id = 1; + + rv = node->HandleMessage(NODE_REGISTERED,&msg,sizeof(msg)); + + // register existing inputs and outputs with the + // media_server, this allows GetLiveNodes() to work + // with created, but unconnected nodes. + if (node->Kinds() & B_BUFFER_PRODUCER) { + Stack stack; + if (B_OK == GetAllOutputs(node->Node(), &stack)) + PublishOutputs(node->Node(), &stack); + } else if (node->Kinds() & B_BUFFER_CONSUMER) { + Stack stack; + if (B_OK == GetAllInputs(node->Node(), &stack)) + PublishInputs(node->Node(), &stack); + } - return node->HandleMessage(NODE_REGISTERED,&msg,sizeof(msg)); + return rv; } diff --git a/src/servers/media/ServerInterface.h b/src/servers/media/ServerInterface.h index f280a9e378..02a701d695 100644 --- a/src/servers/media/ServerInterface.h +++ b/src/servers/media/ServerInterface.h @@ -62,8 +62,6 @@ enum { NODE_REGISTERED, NODE_SET_TIMESOURCE, NODE_REQUEST_COMPLETED, - CONSUMER_GET_NEXT_INPUT, - CONSUMER_DISPOSE_INPUT_COOKIE, CONSUMER_BUFFER_RECEIVED, CONSUMER_PRODUCER_DATA_STATUS, CONSUMER_GET_LATENCY_FOR, @@ -77,8 +75,6 @@ enum { PRODUCER_FORMAT_CHANGE_REQUESTED, PRODUCER_SET_BUFFER_GROUP, PRODUCER_GET_LATENCY, - PRODUCER_GET_NEXT_OUTPUT, - PRODUCER_DISPOSE_OUTPUT_COOKIE, PRODUCER_GET_INITIAL_LATENCY, PRODUCER_FORMAT_SUGGESTION_REQUESTED, PRODUCER_DISCONNECT, @@ -257,24 +253,6 @@ struct xfer_producer_get_latency_reply status_t result; }; -struct xfer_producer_get_next_output -{ - int32 cookie; - port_id reply_port; -}; - -struct xfer_producer_get_next_output_reply -{ - int32 cookie; - media_output output; - status_t result; -}; - -struct xfer_producer_dispose_output_cookie -{ - int32 cookie; -}; - struct xfer_producer_set_buffer_group { media_source source; @@ -381,24 +359,6 @@ struct xfer_node_set_timesource media_node_id timesource_id; }; -struct xfer_consumer_get_next_input -{ - int32 cookie; - port_id reply_port; -}; - -struct xfer_consumer_get_next_input_reply -{ - int32 cookie; - media_input input; - status_t result; -}; - -struct xfer_consumer_dispose_input_cookie -{ - int32 cookie; -}; - struct xfer_consumer_buffer_received { media_buffer_id buffer; diff --git a/src/servers/media/media_server.cpp b/src/servers/media/media_server.cpp index fdf2dc112c..95e2b6a9e5 100644 --- a/src/servers/media/media_server.cpp +++ b/src/servers/media/media_server.cpp @@ -169,6 +169,24 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size) break; } + case SERVER_PUBLISH_INPUTS: + { + server_publish_inputs_request *request = (server_publish_inputs_request *)data; + server_publish_inputs_reply reply; + // XXX do something here + request->SendReply(B_ERROR, &reply, sizeof(reply)); + break; + } + + case SERVER_PUBLISH_OUTPUTS: + { + server_publish_outputs_request *request = (server_publish_outputs_request *)data; + server_publish_outputs_reply reply; + // XXX do something here + request->SendReply(B_ERROR, &reply, sizeof(reply)); + break; + } + case SERVER_GET_NODE: { server_get_node_request *request = (server_get_node_request *)data;