added more BMediaRoster functionality

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1359 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2002-10-04 00:45:20 +00:00
parent 645433765e
commit 3620737cb7
7 changed files with 472 additions and 149 deletions
+76
View File
@@ -69,8 +69,14 @@ enum {
enum { enum {
SERVER_GET_NODE = 1000, SERVER_GET_NODE = 1000,
SERVER_SET_NODE, SERVER_SET_NODE,
SERVER_PUBLISH_INPUTS,
SERVER_PUBLISH_OUTPUTS,
CONSUMER_GET_NEXT_INPUT,
CONSUMER_DISPOSE_INPUT_COOKIE,
CONSUMER_ACCEPT_FORMAT, CONSUMER_ACCEPT_FORMAT,
CONSUMER_CONNECTED, CONSUMER_CONNECTED,
PRODUCER_GET_NEXT_OUTPUT,
PRODUCER_DISPOSE_OUTPUT_COOKIE,
PRODUCER_FORMAT_PROPOSAL, PRODUCER_FORMAT_PROPOSAL,
PRODUCER_PREPARE_TO_CONNECT, PRODUCER_PREPARE_TO_CONNECT,
PRODUCER_CONNECT, PRODUCER_CONNECT,
@@ -89,6 +95,12 @@ enum node_type
SYSTEM_TIME_SOURCE 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 struct addonserver_instantiate_dormant_node_request : public request_data
{ {
@@ -192,4 +204,68 @@ struct consumer_connected_reply : public reply_data
media_input input; 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 #endif // _DATA_EXCHANGE_H
+7 -5
View File
@@ -341,18 +341,20 @@ BBufferConsumer::HandleMessage(int32 message,
case CONSUMER_GET_NEXT_INPUT: case CONSUMER_GET_NEXT_INPUT:
{ {
const xfer_consumer_get_next_input *request = (const xfer_consumer_get_next_input *)rawdata; const consumer_get_next_input_request *request = (const consumer_get_next_input_request *)rawdata;
xfer_consumer_get_next_input_reply reply; consumer_get_next_input_reply reply;
reply.cookie = request->cookie; reply.cookie = request->cookie;
reply.result = GetNextInput(&reply.cookie, &reply.input); rv = GetNextInput(&reply.cookie, &reply.input);
write_port(request->reply_port, 0, &reply, sizeof(reply)); request->SendReply(rv, &reply, sizeof(reply));
return B_OK; return B_OK;
} }
case CONSUMER_DISPOSE_INPUT_COOKIE: 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); DisposeInputCookie(request->cookie);
request->SendReply(B_OK, &reply, sizeof(reply));
return B_OK; return B_OK;
} }
+7 -5
View File
@@ -184,18 +184,20 @@ BBufferProducer::HandleMessage(int32 message,
case PRODUCER_GET_NEXT_OUTPUT: case PRODUCER_GET_NEXT_OUTPUT:
{ {
const xfer_producer_get_next_output *request = (const xfer_producer_get_next_output *)rawdata; const producer_get_next_output_request *request = (const producer_get_next_output_request *)rawdata;
xfer_producer_get_next_output_reply reply; producer_get_next_output_reply reply;
reply.cookie = request->cookie; reply.cookie = request->cookie;
reply.result = GetNextOutput(&reply.cookie, &reply.output); rv = GetNextOutput(&reply.cookie, &reply.output);
write_port(request->reply_port, 0, &reply, sizeof(reply)); request->SendReply(rv, &reply, sizeof(reply));
return B_OK; return B_OK;
} }
case PRODUCER_DISPOSE_OUTPUT_COOKIE: 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); DisposeOutputCookie(request->cookie);
request->SendReply(B_OK, &reply, sizeof(reply));
return B_OK; return B_OK;
} }
+26
View File
@@ -13,6 +13,7 @@
#include <string.h> #include <string.h>
#include "SystemTimeSource.h" #include "SystemTimeSource.h"
#include "debug.h" #include "debug.h"
#include "DataExchange.h"
#include "ServerInterface.h" #include "ServerInterface.h"
#include "Notifications.h" #include "Notifications.h"
@@ -501,6 +502,31 @@ BMediaNode::HandleBadMessage(int32 code,
size_t size) size_t size)
{ {
CALLED(); 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<const request_data *>(buffer);
reply_data reply;
request->SendReply(B_ERROR, &reply, sizeof(reply));
break;
}
}
} }
+326 -87
View File
@@ -14,17 +14,18 @@
#undef DEBUG #undef DEBUG
#define DEBUG 3 #define DEBUG 3
#include "debug.h" #include "debug.h"
#include "TStack.h"
#include "PortPool.h" #include "PortPool.h"
#include "ServerInterface.h" #include "ServerInterface.h"
#include "DataExchange.h" #include "DataExchange.h"
#include "DormantNodeManager.h" #include "DormantNodeManager.h"
#include "Notifications.h" #include "Notifications.h"
using namespace BPrivate::media;
namespace BPrivate { namespace media { namespace BPrivate { namespace media {
extern team_id team; extern team_id team;
}; }; } } // BPrivate::media
using namespace BPrivate::media;
// the BMediaRoster destructor is private, // the BMediaRoster destructor is private,
// but _DefaultDeleter is a friend class of // but _DefaultDeleter is a friend class of
@@ -37,14 +38,17 @@ public:
_DefaultDeleter _deleter; _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 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 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<media_output> *stack);
status_t GetAllInputs(const media_node & node, Stack<media_input> *stack);
status_t PublishOutputs(const media_node & node, Stack<media_output> *stack);
status_t PublishInputs(const media_node & node, Stack<media_input> *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) if (out_node == NULL)
return B_BAD_VALUE; 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; 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_request request;
server_set_node_reply reply; 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)); return QueryServer(SERVER_SET_NODE, &request, sizeof(request), &reply, sizeof(reply));
} }
}; status_t
GetAllOutputs(const media_node & node, Stack<media_output> *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<media_input> *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<media_output> *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<media_output *>(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<media_input> *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<media_input *>(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 * public BMediaRoster
@@ -95,7 +238,7 @@ status_t
BMediaRoster::GetVideoInput(media_node * out_node) BMediaRoster::GetVideoInput(media_node * out_node)
{ {
CALLED(); 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) BMediaRoster::GetAudioInput(media_node * out_node)
{ {
CALLED(); 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) BMediaRoster::GetVideoOutput(media_node * out_node)
{ {
CALLED(); 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) BMediaRoster::GetAudioMixer(media_node * out_node)
{ {
CALLED(); 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) BMediaRoster::GetAudioOutput(media_node * out_node)
{ {
CALLED(); 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) BString * out_input_name)
{ {
CALLED(); 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) BMediaRoster::GetTimeSource(media_node * out_node)
{ {
CALLED(); 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) BMediaRoster::SetVideoInput(const media_node & producer)
{ {
CALLED(); 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) BMediaRoster::SetVideoInput(const dormant_node_info & producer)
{ {
CALLED(); 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) BMediaRoster::SetAudioInput(const media_node & producer)
{ {
CALLED(); 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) BMediaRoster::SetAudioInput(const dormant_node_info & producer)
{ {
CALLED(); 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) BMediaRoster::SetVideoOutput(const media_node & consumer)
{ {
CALLED(); 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) BMediaRoster::SetVideoOutput(const dormant_node_info & consumer)
{ {
CALLED(); 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) BMediaRoster::SetAudioOutput(const media_node & consumer)
{ {
CALLED(); 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) BMediaRoster::SetAudioOutput(const media_input & input_to_output)
{ {
CALLED(); 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) BMediaRoster::SetAudioOutput(const dormant_node_info & consumer)
{ {
CALLED(); 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) BMediaRoster::GetSystemTimeSource(media_node * clone)
{ {
CALLED(); CALLED();
return MediaKitPrivate::GetNode(SYSTEM_TIME_SOURCE, clone); return GetNode(SYSTEM_TIME_SOURCE, clone);
} }
@@ -629,8 +772,35 @@ BMediaRoster::GetFreeInputsFor(const media_node & node,
int32 * out_total_count, int32 * out_total_count,
media_type filter_type) media_type filter_type)
{ {
UNIMPLEMENTED(); CALLED();
return B_ERROR; 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<media_input> 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;
} }
@@ -640,8 +810,33 @@ BMediaRoster::GetConnectedInputsFor(const media_node & node,
int32 buf_num_inputs, int32 buf_num_inputs,
int32 * out_total_count) int32 * out_total_count)
{ {
UNIMPLEMENTED(); CALLED();
return B_ERROR; 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<media_input> 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;
} }
@@ -657,38 +852,25 @@ BMediaRoster::GetAllInputsFor(const media_node & node,
if (out_inputs == NULL || out_total_count == NULL) if (out_inputs == NULL || out_total_count == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
Stack<media_input> stack;
media_input *input;
status_t rv; status_t rv;
status_t rv2;
port_id port;
int32 code;
int32 cookie;
port = _PortPool->GetPort(); rv = GetAllInputs(node, &stack);
if (B_OK != rv)
return rv;
*out_total_count = 0; *out_total_count = 0;
cookie = 0; for (int32 i = 0; stack.GetPointerAt(i, &input); i++) {
rv = B_OK; out_inputs[i] = *input;
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_total_count += 1;
out_inputs[i] = reply.input; buf_num_inputs -= 1;
cookie = reply.cookie; if (buf_num_inputs == 0)
break;
} }
_PortPool->PutPort(port);
xfer_consumer_dispose_input_cookie msg2; PublishInputs(node, &stack);
msg2.cookie = cookie; return B_OK;
rv2 = write_port(node.port, CONSUMER_DISPOSE_INPUT_COOKIE, &msg2, sizeof(msg2));
return (rv < B_OK) ? rv : rv2;
} }
@@ -699,8 +881,35 @@ BMediaRoster::GetFreeOutputsFor(const media_node & node,
int32 * out_total_count, int32 * out_total_count,
media_type filter_type) media_type filter_type)
{ {
UNIMPLEMENTED(); CALLED();
return B_ERROR; 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<media_output> 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 buf_num_outputs,
int32 * out_total_count) int32 * out_total_count)
{ {
UNIMPLEMENTED(); CALLED();
return B_ERROR; 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<media_output> 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;
} }
@@ -727,38 +961,25 @@ BMediaRoster::GetAllOutputsFor(const media_node & node,
if (out_outputs == NULL || out_total_count == NULL) if (out_outputs == NULL || out_total_count == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
Stack<media_output> stack;
media_output *output;
status_t rv; status_t rv;
status_t rv2;
port_id port;
int32 code;
int32 cookie;
port = _PortPool->GetPort(); rv = GetAllOutputs(node, &stack);
if (B_OK != rv)
return rv;
*out_total_count = 0; *out_total_count = 0;
cookie = 0; for (int32 i = 0; stack.GetPointerAt(i, &output); i++) {
rv = B_OK; out_outputs[i] = *output;
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_total_count += 1;
out_outputs[i] = reply.output; buf_num_outputs -= 1;
cookie = reply.cookie; if (buf_num_outputs == 0)
break;
} }
_PortPool->PutPort(port);
xfer_producer_dispose_output_cookie msg2; PublishOutputs(node, &stack);
msg2.cookie = cookie; return B_OK;
rv2 = write_port(node.port, PRODUCER_DISPOSE_OUTPUT_COOKIE, &msg2, sizeof(msg2));
return (rv < B_OK) ? rv : rv2;
} }
@@ -862,10 +1083,28 @@ BMediaRoster::RegisterNode(BMediaNode * node)
if (node == NULL) if (node == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
status_t rv;
// XXX fix node registration
xfer_node_registered msg; xfer_node_registered msg;
msg.node_id = 1; msg.node_id = 1;
return node->HandleMessage(NODE_REGISTERED,&msg,sizeof(msg)); 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<media_output> stack;
if (B_OK == GetAllOutputs(node->Node(), &stack))
PublishOutputs(node->Node(), &stack);
} else if (node->Kinds() & B_BUFFER_CONSUMER) {
Stack<media_input> stack;
if (B_OK == GetAllInputs(node->Node(), &stack))
PublishInputs(node->Node(), &stack);
}
return rv;
} }
-40
View File
@@ -62,8 +62,6 @@ enum {
NODE_REGISTERED, NODE_REGISTERED,
NODE_SET_TIMESOURCE, NODE_SET_TIMESOURCE,
NODE_REQUEST_COMPLETED, NODE_REQUEST_COMPLETED,
CONSUMER_GET_NEXT_INPUT,
CONSUMER_DISPOSE_INPUT_COOKIE,
CONSUMER_BUFFER_RECEIVED, CONSUMER_BUFFER_RECEIVED,
CONSUMER_PRODUCER_DATA_STATUS, CONSUMER_PRODUCER_DATA_STATUS,
CONSUMER_GET_LATENCY_FOR, CONSUMER_GET_LATENCY_FOR,
@@ -77,8 +75,6 @@ enum {
PRODUCER_FORMAT_CHANGE_REQUESTED, PRODUCER_FORMAT_CHANGE_REQUESTED,
PRODUCER_SET_BUFFER_GROUP, PRODUCER_SET_BUFFER_GROUP,
PRODUCER_GET_LATENCY, PRODUCER_GET_LATENCY,
PRODUCER_GET_NEXT_OUTPUT,
PRODUCER_DISPOSE_OUTPUT_COOKIE,
PRODUCER_GET_INITIAL_LATENCY, PRODUCER_GET_INITIAL_LATENCY,
PRODUCER_FORMAT_SUGGESTION_REQUESTED, PRODUCER_FORMAT_SUGGESTION_REQUESTED,
PRODUCER_DISCONNECT, PRODUCER_DISCONNECT,
@@ -257,24 +253,6 @@ struct xfer_producer_get_latency_reply
status_t result; 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 struct xfer_producer_set_buffer_group
{ {
media_source source; media_source source;
@@ -381,24 +359,6 @@ struct xfer_node_set_timesource
media_node_id timesource_id; 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 struct xfer_consumer_buffer_received
{ {
media_buffer_id buffer; media_buffer_id buffer;
+18
View File
@@ -169,6 +169,24 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
break; 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: case SERVER_GET_NODE:
{ {
server_get_node_request *request = (server_get_node_request *)data; server_get_node_request *request = (server_get_node_request *)data;