xref: /haiku/src/kits/media/MediaRoster.cpp (revision ab9afde3054ea74bb047fcb56eeedcaa3baf47a8)
1255a01c7Sbeveloper /*
265b73ae4SMarcus Overhagen  * Copyright (c) 2002-2006 Marcus Overhagen <Marcus@Overhagen.de>
3255a01c7Sbeveloper  *
4255a01c7Sbeveloper  * Permission is hereby granted, free of charge, to any person obtaining
5255a01c7Sbeveloper  * a copy of this software and associated documentation files or portions
6255a01c7Sbeveloper  * thereof (the "Software"), to deal in the Software without restriction,
7255a01c7Sbeveloper  * including without limitation the rights to use, copy, modify, merge,
8255a01c7Sbeveloper  * publish, distribute, sublicense, and/or sell copies of the Software,
9255a01c7Sbeveloper  * and to permit persons to whom the Software is furnished to do so, subject
10255a01c7Sbeveloper  * to the following conditions:
11255a01c7Sbeveloper  *
12255a01c7Sbeveloper  *  * Redistributions of source code must retain the above copyright notice,
13255a01c7Sbeveloper  *    this list of conditions and the following disclaimer.
14255a01c7Sbeveloper  *
15255a01c7Sbeveloper  *  * Redistributions in binary form must reproduce the above copyright notice
16255a01c7Sbeveloper  *    in the  binary, as well as this list of conditions and the following
17255a01c7Sbeveloper  *    disclaimer in the documentation and/or other materials provided with
18255a01c7Sbeveloper  *    the distribution.
19255a01c7Sbeveloper  *
20255a01c7Sbeveloper  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21255a01c7Sbeveloper  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22255a01c7Sbeveloper  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23255a01c7Sbeveloper  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24255a01c7Sbeveloper  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25255a01c7Sbeveloper  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26255a01c7Sbeveloper  * THE SOFTWARE.
27255a01c7Sbeveloper  *
28255a01c7Sbeveloper  */
29255a01c7Sbeveloper 
30255a01c7Sbeveloper /* to comply with the license above, do not remove the following line */
3165b73ae4SMarcus Overhagen char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus Overhagen <Marcus@Overhagen.de>";
32255a01c7Sbeveloper 
3352a38012Sejakowatz #include <MediaRoster.h>
3452a38012Sejakowatz #include <Locker.h>
3552a38012Sejakowatz #include <Message.h>
3652a38012Sejakowatz #include <Messenger.h>
3752a38012Sejakowatz #include <StopWatch.h>
3852a38012Sejakowatz #include <OS.h>
3952a38012Sejakowatz #include <String.h>
4052a38012Sejakowatz #include <TimeSource.h>
4160f15390Sbeveloper #include <ParameterWeb.h>
424d2d96e0Sbeveloper #include <BufferProducer.h>
434d2d96e0Sbeveloper #include <BufferConsumer.h>
4452a38012Sejakowatz #include "debug.h"
458b04ffc1Sbeveloper #include "MediaRosterEx.h"
4640f36b03Sbeveloper #include "MediaMisc.h"
4752a38012Sejakowatz #include "PortPool.h"
480a483e72SIngo Weinhold #include "ServerInterface.h"
49f4925104Sbeveloper #include "DataExchange.h"
5016b7eea4Sbeveloper #include "DormantNodeManager.h"
51f4925104Sbeveloper #include "Notifications.h"
52835140c8Sbeveloper #include "TimeSourceObjectManager.h"
5352a38012Sejakowatz 
54f4925104Sbeveloper namespace BPrivate { namespace media {
5552a38012Sejakowatz 
5652a38012Sejakowatz 	// the BMediaRoster destructor is private,
5752a38012Sejakowatz 	// but _DefaultDeleter is a friend class of
5852a38012Sejakowatz 	// the BMediaRoster an thus can delete it
598b04ffc1Sbeveloper 	class DefaultDeleter
6052a38012Sejakowatz 	{
6152a38012Sejakowatz 	public:
628b04ffc1Sbeveloper 		~DefaultDeleter()
636396865dSbeveloper 		{
646396865dSbeveloper 			if (BMediaRoster::_sDefault) {
656396865dSbeveloper 				BMediaRoster::_sDefault->Lock();
666396865dSbeveloper 				BMediaRoster::_sDefault->Quit();
676396865dSbeveloper 			}
686396865dSbeveloper 		}
698b04ffc1Sbeveloper 	};
7052a38012Sejakowatz 
718b04ffc1Sbeveloper } } // BPrivate::media
728b04ffc1Sbeveloper using namespace BPrivate::media;
7352a38012Sejakowatz 
748b04ffc1Sbeveloper // DefaultDeleter will delete the BMediaRoster object in it's destructor.
758b04ffc1Sbeveloper DefaultDeleter _deleter;
7652a38012Sejakowatz 
77dcfb6bfcSJérôme Duval BMediaRosterEx::BMediaRosterEx(status_t * out_error)
78dcfb6bfcSJérôme Duval 	: BMediaRoster()
79dcfb6bfcSJérôme Duval {
80dcfb6bfcSJérôme Duval 	status_t rv;
81dcfb6bfcSJérôme Duval 	// register this application with the media server
82dcfb6bfcSJérôme Duval 	server_register_app_request request;
83dcfb6bfcSJérôme Duval 	server_register_app_reply reply;
84dcfb6bfcSJérôme Duval 	request.team = team;
85dcfb6bfcSJérôme Duval 	request.messenger = BMessenger(NULL, this);
86dcfb6bfcSJérôme Duval 	rv = QueryServer(SERVER_REGISTER_APP, &request, sizeof(request), &reply, sizeof(reply));
878496c38aSbeveloper 	*out_error = (rv != B_OK) ? B_MEDIA_SYSTEM_FAILURE : B_OK;
88dcfb6bfcSJérôme Duval }
89dcfb6bfcSJérôme Duval 
903620737cSbeveloper status_t
9154187cc6Sbeveloper BMediaRosterEx::SaveNodeConfiguration(BMediaNode *node)
9254187cc6Sbeveloper {
9354187cc6Sbeveloper 	BMediaAddOn *addon;
9454187cc6Sbeveloper 	media_addon_id addonid;
9554187cc6Sbeveloper 	int32 flavorid;
9654187cc6Sbeveloper 	addon = node->AddOn(&flavorid);
9754187cc6Sbeveloper 	if (!addon) {
9860f15390Sbeveloper 		// XXX this check incorrectly triggers on BeOS R5 BT848 node
995ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::SaveNodeConfiguration node %ld not instantiated from BMediaAddOn!\n", node->ID());
10054187cc6Sbeveloper 		return B_ERROR;
10154187cc6Sbeveloper 	}
10254187cc6Sbeveloper 	addonid = addon->AddonID();
10354187cc6Sbeveloper 
10454187cc6Sbeveloper 	// XXX fix this
10554187cc6Sbeveloper 	printf("### BMediaRosterEx::SaveNodeConfiguration should save addon-id %ld, flavor-id %ld config NOW!\n", addonid, flavorid);
10654187cc6Sbeveloper 	return B_OK;
10754187cc6Sbeveloper }
10854187cc6Sbeveloper 
10954187cc6Sbeveloper status_t
11054187cc6Sbeveloper BMediaRosterEx::LoadNodeConfiguration(media_addon_id addonid, int32 flavorid, BMessage *out_msg)
11154187cc6Sbeveloper {
11254187cc6Sbeveloper 	// XXX fix this
11354187cc6Sbeveloper 	out_msg->MakeEmpty(); // to be fully R5 compliant
11454187cc6Sbeveloper 	printf("### BMediaRosterEx::LoadNodeConfiguration should load addon-id %ld, flavor-id %ld config NOW!\n", addonid, flavorid);
11554187cc6Sbeveloper 	return B_OK;
11654187cc6Sbeveloper }
11754187cc6Sbeveloper 
11854187cc6Sbeveloper status_t
11973794717Sbeveloper BMediaRosterEx::IncrementAddonFlavorInstancesCount(media_addon_id addonid, int32 flavorid)
12054187cc6Sbeveloper {
12173794717Sbeveloper 	server_change_addon_flavor_instances_count_request request;
12273794717Sbeveloper 	server_change_addon_flavor_instances_count_reply reply;
12373794717Sbeveloper 
12473794717Sbeveloper 	request.addonid = addonid;
12573794717Sbeveloper 	request.flavorid = flavorid;
12673794717Sbeveloper 	request.delta = 1;
12773794717Sbeveloper 	request.team = team;
12873794717Sbeveloper 	return QueryServer(SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT, &request, sizeof(request), &reply, sizeof(reply));
12954187cc6Sbeveloper }
13054187cc6Sbeveloper 
13154187cc6Sbeveloper status_t
13273794717Sbeveloper BMediaRosterEx::DecrementAddonFlavorInstancesCount(media_addon_id addonid, int32 flavorid)
13354187cc6Sbeveloper {
13473794717Sbeveloper 	server_change_addon_flavor_instances_count_request request;
13573794717Sbeveloper 	server_change_addon_flavor_instances_count_reply reply;
13673794717Sbeveloper 
13773794717Sbeveloper 	request.addonid = addonid;
13873794717Sbeveloper 	request.flavorid = flavorid;
13973794717Sbeveloper 	request.delta = -1;
14073794717Sbeveloper 	request.team = team;
14173794717Sbeveloper 	return QueryServer(SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT, &request, sizeof(request), &reply, sizeof(reply));
14254187cc6Sbeveloper }
14354187cc6Sbeveloper 
14454187cc6Sbeveloper status_t
14554187cc6Sbeveloper BMediaRosterEx::SetNodeCreator(media_node_id node, team_id creator)
14654187cc6Sbeveloper {
14754187cc6Sbeveloper 	server_set_node_creator_request request;
14854187cc6Sbeveloper 	server_set_node_creator_reply reply;
14954187cc6Sbeveloper 
15054187cc6Sbeveloper 	request.node = node;
15154187cc6Sbeveloper 	request.creator = creator;
15254187cc6Sbeveloper 	return QueryServer(SERVER_SET_NODE_CREATOR, &request, sizeof(request), &reply, sizeof(reply));
15354187cc6Sbeveloper }
15454187cc6Sbeveloper 
15554187cc6Sbeveloper status_t
1568b04ffc1Sbeveloper BMediaRosterEx::GetNode(node_type type, media_node * out_node, int32 * out_input_id, BString * out_input_name)
15752a38012Sejakowatz {
15852a38012Sejakowatz 	if (out_node == NULL)
15952a38012Sejakowatz 		return B_BAD_VALUE;
16052a38012Sejakowatz 
1618c6a6096Sbeveloper 	server_get_node_request request;
1628c6a6096Sbeveloper 	server_get_node_reply reply;
16352a38012Sejakowatz 	status_t rv;
16452a38012Sejakowatz 
1658c6a6096Sbeveloper 	request.type = type;
1669e9417d2Sbeveloper 	request.team = team;
1678c6a6096Sbeveloper 	rv = QueryServer(SERVER_GET_NODE, &request, sizeof(request), &reply, sizeof(reply));
1688c6a6096Sbeveloper 	if (rv != B_OK)
1698c6a6096Sbeveloper 		return rv;
17052a38012Sejakowatz 
17152a38012Sejakowatz 	*out_node = reply.node;
17252a38012Sejakowatz 	if (out_input_id)
17352a38012Sejakowatz 		*out_input_id = reply.input_id;
17452a38012Sejakowatz 	if (out_input_name)
17552a38012Sejakowatz 		*out_input_name = reply.input_name;
1768c6a6096Sbeveloper 	return rv;
17752a38012Sejakowatz }
17852a38012Sejakowatz 
1793620737cSbeveloper status_t
1808b04ffc1Sbeveloper BMediaRosterEx::SetNode(node_type type, const media_node *node, const dormant_node_info *info, const media_input *input)
18152a38012Sejakowatz {
1828c6a6096Sbeveloper 	server_set_node_request request;
1838c6a6096Sbeveloper 	server_set_node_reply reply;
18452a38012Sejakowatz 
1858c6a6096Sbeveloper 	request.type = type;
1868c6a6096Sbeveloper 	request.use_node = node ? true : false;
18752a38012Sejakowatz 	if (node)
1888c6a6096Sbeveloper 		request.node = *node;
1898c6a6096Sbeveloper 	request.use_dni = info ? true : false;
19052a38012Sejakowatz 	if (info)
1918c6a6096Sbeveloper 		request.dni = *info;
1928c6a6096Sbeveloper 	request.use_input = input ? true : false;
19352a38012Sejakowatz 	if (input)
1948c6a6096Sbeveloper 		request.input = *input;
19552a38012Sejakowatz 
1968c6a6096Sbeveloper 	return QueryServer(SERVER_SET_NODE, &request, sizeof(request), &reply, sizeof(reply));
19752a38012Sejakowatz }
19852a38012Sejakowatz 
1993620737cSbeveloper status_t
2008b04ffc1Sbeveloper BMediaRosterEx::GetAllOutputs(const media_node & node, List<media_output> *list)
2013620737cSbeveloper {
2023620737cSbeveloper 	int32 cookie;
2033620737cSbeveloper 	status_t rv;
2043620737cSbeveloper 	status_t result;
2053620737cSbeveloper 
2065ac4fbd7Sbeveloper 	PRINT(4, "BMediaRosterEx::GetAllOutputs() node %ld, port %ld\n", node.node, node.port);
2075ac4fbd7Sbeveloper 
20865b73ae4SMarcus Overhagen 	if (!(node.kind & B_BUFFER_PRODUCER)) {
20965b73ae4SMarcus Overhagen 		ERROR("BMediaRosterEx::GetAllOutputs: node %ld is not a B_BUFFER_PRODUCER\n", node.node);
21065b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_NODE;
21165b73ae4SMarcus Overhagen 	}
21265b73ae4SMarcus Overhagen 
2133620737cSbeveloper 	result = B_OK;
2143620737cSbeveloper 	cookie = 0;
21576669a29Sbeveloper 	list->MakeEmpty();
2163620737cSbeveloper 	for (;;) {
2173620737cSbeveloper 		producer_get_next_output_request request;
2183620737cSbeveloper 		producer_get_next_output_reply reply;
2193620737cSbeveloper 		request.cookie = cookie;
2200caff283Sbeveloper 		rv = QueryPort(node.port, PRODUCER_GET_NEXT_OUTPUT, &request, sizeof(request), &reply, sizeof(reply));
2213620737cSbeveloper 		if (rv != B_OK)
2223620737cSbeveloper 			break;
2233620737cSbeveloper 		cookie = reply.cookie;
22476669a29Sbeveloper 		if (!list->Insert(reply.output)) {
2255ac4fbd7Sbeveloper 			ERROR("GetAllOutputs: list->Insert failed\n");
2263620737cSbeveloper 			result = B_ERROR;
2273620737cSbeveloper 		}
2285ac4fbd7Sbeveloper 		#if DEBUG >= 3
2295ac4fbd7Sbeveloper 			PRINT(3," next cookie %ld, ", cookie);
2305ac4fbd7Sbeveloper 			PRINT_OUTPUT("output ", reply.output);
2315ac4fbd7Sbeveloper 		#endif
2323620737cSbeveloper 	}
2333620737cSbeveloper 
2343620737cSbeveloper 	producer_dispose_output_cookie_request request;
2353620737cSbeveloper 	producer_dispose_output_cookie_reply reply;
2360caff283Sbeveloper 	QueryPort(node.port, PRODUCER_DISPOSE_OUTPUT_COOKIE, &request, sizeof(request), &reply, sizeof(reply));
2373620737cSbeveloper 
2383620737cSbeveloper 	return result;
2393620737cSbeveloper }
2403620737cSbeveloper 
2413620737cSbeveloper status_t
2424d2d96e0Sbeveloper BMediaRosterEx::GetAllOutputs(BBufferProducer *node, List<media_output> *list)
2434d2d96e0Sbeveloper {
2444d2d96e0Sbeveloper 	int32 cookie;
2454d2d96e0Sbeveloper 	status_t result;
2464d2d96e0Sbeveloper 
2474d2d96e0Sbeveloper 	PRINT(4, "BMediaRosterEx::GetAllOutputs() (by pointer) node %ld, port %ld\n", node->ID(), node->ControlPort());
2484d2d96e0Sbeveloper 
2494d2d96e0Sbeveloper 	result = B_OK;
2504d2d96e0Sbeveloper 	cookie = 0;
2514d2d96e0Sbeveloper 	list->MakeEmpty();
2524d2d96e0Sbeveloper 	for (;;) {
2534d2d96e0Sbeveloper 		media_output output;
2544d2d96e0Sbeveloper 		if (B_OK != node->GetNextOutput(&cookie, &output))
2554d2d96e0Sbeveloper 			break;
2564d2d96e0Sbeveloper 		if (!list->Insert(output)) {
2574d2d96e0Sbeveloper 			ERROR("GetAllOutputs: list->Insert failed\n");
2584d2d96e0Sbeveloper 			result = B_ERROR;
2594d2d96e0Sbeveloper 		}
2604d2d96e0Sbeveloper 		#if DEBUG >= 3
2614d2d96e0Sbeveloper 			PRINT(3," next cookie %ld, ", cookie);
2624d2d96e0Sbeveloper 			PRINT_OUTPUT("output ", output);
2634d2d96e0Sbeveloper 		#endif
2644d2d96e0Sbeveloper 	}
2654d2d96e0Sbeveloper 	node->DisposeOutputCookie(cookie);
2664d2d96e0Sbeveloper 	return result;
2674d2d96e0Sbeveloper }
2684d2d96e0Sbeveloper 
2694d2d96e0Sbeveloper status_t
2708b04ffc1Sbeveloper BMediaRosterEx::GetAllInputs(const media_node & node, List<media_input> *list)
2713620737cSbeveloper {
2723620737cSbeveloper 	int32 cookie;
2733620737cSbeveloper 	status_t rv;
2743620737cSbeveloper 	status_t result;
2753620737cSbeveloper 
2765ac4fbd7Sbeveloper 	PRINT(4, "BMediaRosterEx::GetAllInputs() node %ld, port %ld\n", node.node, node.port);
2775ac4fbd7Sbeveloper 
27865b73ae4SMarcus Overhagen 	if (!(node.kind & B_BUFFER_CONSUMER)) {
27965b73ae4SMarcus Overhagen 		ERROR("BMediaRosterEx::GetAllInputs: node %ld is not a B_BUFFER_CONSUMER\n", node.node);
28065b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_NODE;
28165b73ae4SMarcus Overhagen 	}
28265b73ae4SMarcus Overhagen 
2833620737cSbeveloper 	result = B_OK;
2843620737cSbeveloper 	cookie = 0;
28576669a29Sbeveloper 	list->MakeEmpty();
2863620737cSbeveloper 	for (;;) {
2873620737cSbeveloper 		consumer_get_next_input_request request;
2883620737cSbeveloper 		consumer_get_next_input_reply reply;
2893620737cSbeveloper 		request.cookie = cookie;
2900caff283Sbeveloper 		rv = QueryPort(node.port, CONSUMER_GET_NEXT_INPUT, &request, sizeof(request), &reply, sizeof(reply));
2913620737cSbeveloper 		if (rv != B_OK)
2923620737cSbeveloper 			break;
2933620737cSbeveloper 		cookie = reply.cookie;
29476669a29Sbeveloper 		if (!list->Insert(reply.input)) {
2955ac4fbd7Sbeveloper 			ERROR("GetAllInputs: list->Insert failed\n");
2963620737cSbeveloper 			result = B_ERROR;
2973620737cSbeveloper 		}
2985ac4fbd7Sbeveloper 		#if DEBUG >= 3
2995ac4fbd7Sbeveloper 			PRINT(3," next cookie %ld, ", cookie);
3005ac4fbd7Sbeveloper 			PRINT_OUTPUT("input ", reply.input);
3015ac4fbd7Sbeveloper 		#endif
3023620737cSbeveloper 	}
3033620737cSbeveloper 
3043620737cSbeveloper 	consumer_dispose_input_cookie_request request;
3053620737cSbeveloper 	consumer_dispose_input_cookie_reply reply;
3060caff283Sbeveloper 	QueryPort(node.port, CONSUMER_DISPOSE_INPUT_COOKIE, &request, sizeof(request), &reply, sizeof(reply));
3073620737cSbeveloper 
3083620737cSbeveloper 	return result;
3093620737cSbeveloper }
3103620737cSbeveloper 
3113620737cSbeveloper status_t
3124d2d96e0Sbeveloper BMediaRosterEx::GetAllInputs(BBufferConsumer *node, List<media_input> *list)
3134d2d96e0Sbeveloper {
3144d2d96e0Sbeveloper 	int32 cookie;
3154d2d96e0Sbeveloper 	status_t result;
3164d2d96e0Sbeveloper 
3174d2d96e0Sbeveloper 	PRINT(4, "BMediaRosterEx::GetAllInputs() (by pointer) node %ld, port %ld\n", node->ID(), node->ControlPort());
3184d2d96e0Sbeveloper 
3194d2d96e0Sbeveloper 	result = B_OK;
3204d2d96e0Sbeveloper 	cookie = 0;
3214d2d96e0Sbeveloper 	list->MakeEmpty();
3224d2d96e0Sbeveloper 	for (;;) {
3234d2d96e0Sbeveloper 		media_input input;
3244d2d96e0Sbeveloper 		if (B_OK != node->GetNextInput(&cookie, &input))
3254d2d96e0Sbeveloper 			break;
3264d2d96e0Sbeveloper 		if (!list->Insert(input)) {
3274d2d96e0Sbeveloper 			ERROR("GetAllInputs: list->Insert failed\n");
3284d2d96e0Sbeveloper 			result = B_ERROR;
3294d2d96e0Sbeveloper 		}
3304d2d96e0Sbeveloper 		#if DEBUG >= 3
3314d2d96e0Sbeveloper 			PRINT(3," next cookie %ld, ", cookie);
3324d2d96e0Sbeveloper 			PRINT_INPUT("input ", input);
3334d2d96e0Sbeveloper 		#endif
3344d2d96e0Sbeveloper 	}
3354d2d96e0Sbeveloper 	node->DisposeInputCookie(cookie);
3364d2d96e0Sbeveloper 	return result;
3374d2d96e0Sbeveloper }
3384d2d96e0Sbeveloper 
3394d2d96e0Sbeveloper status_t
3408b04ffc1Sbeveloper BMediaRosterEx::PublishOutputs(const media_node & node, List<media_output> *list)
3413620737cSbeveloper {
3423620737cSbeveloper 	server_publish_outputs_request request;
3433620737cSbeveloper 	server_publish_outputs_reply reply;
3443620737cSbeveloper 	media_output *output;
3453620737cSbeveloper 	media_output *outputs;
3463620737cSbeveloper 	int32 count;
347a7b41a96Sbeveloper 	status_t rv;
3483620737cSbeveloper 
34976669a29Sbeveloper 	count = list->CountItems();
3503620737cSbeveloper 	TRACE("PublishOutputs: publishing %ld\n", count);
3513620737cSbeveloper 
3523620737cSbeveloper 	request.node = node;
3533620737cSbeveloper 	request.count = count;
3543620737cSbeveloper 	if (count > MAX_OUTPUTS) {
3553620737cSbeveloper 		void *start_addr;
3563620737cSbeveloper 		size_t size;
35740f36b03Sbeveloper 		size = ROUND_UP_TO_PAGE(count * sizeof(media_output));
3583620737cSbeveloper 		request.area = create_area("publish outputs", &start_addr, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
3593620737cSbeveloper 		if (request.area < B_OK) {
3605ac4fbd7Sbeveloper 			ERROR("PublishOutputs: failed to create area, %#lx\n", request.area);
3613620737cSbeveloper 			return (status_t)request.area;
3623620737cSbeveloper 		}
3633620737cSbeveloper 		outputs = static_cast<media_output *>(start_addr);
3643620737cSbeveloper 	} else {
3653620737cSbeveloper 		request.area = -1;
3663620737cSbeveloper 		outputs = request.outputs;
3673620737cSbeveloper 	}
36876669a29Sbeveloper 	TRACE("PublishOutputs: area %ld\n", request.area);
3693620737cSbeveloper 
37076669a29Sbeveloper 	int i;
37176669a29Sbeveloper 	for (i = 0, list->Rewind(); list->GetNext(&output); i++) {
37276669a29Sbeveloper 		ASSERT(i < count);
3733620737cSbeveloper 		outputs[i] = *output;
3743620737cSbeveloper 	}
3753620737cSbeveloper 
376a7b41a96Sbeveloper 	rv = QueryServer(SERVER_PUBLISH_OUTPUTS, &request, sizeof(request), &reply, sizeof(reply));
377a7b41a96Sbeveloper 
378a7b41a96Sbeveloper 	if (request.area != -1)
379a7b41a96Sbeveloper 		delete_area(request.area);
380a7b41a96Sbeveloper 
381a7b41a96Sbeveloper 	return rv;
3823620737cSbeveloper }
3833620737cSbeveloper 
3843620737cSbeveloper status_t
3858b04ffc1Sbeveloper BMediaRosterEx::PublishInputs(const media_node & node, List<media_input> *list)
3863620737cSbeveloper {
3873620737cSbeveloper 	server_publish_inputs_request request;
3883620737cSbeveloper 	server_publish_inputs_reply reply;
3893620737cSbeveloper 	media_input *input;
3903620737cSbeveloper 	media_input *inputs;
3913620737cSbeveloper 	int32 count;
392a7b41a96Sbeveloper 	status_t rv;
3933620737cSbeveloper 
39476669a29Sbeveloper 	count = list->CountItems();
3953620737cSbeveloper 	TRACE("PublishInputs: publishing %ld\n", count);
3963620737cSbeveloper 
3973620737cSbeveloper 	request.node = node;
3983620737cSbeveloper 	request.count = count;
3993620737cSbeveloper 	if (count > MAX_INPUTS) {
4003620737cSbeveloper 		void *start_addr;
4013620737cSbeveloper 		size_t size;
40240f36b03Sbeveloper 		size = ROUND_UP_TO_PAGE(count * sizeof(media_input));
4033620737cSbeveloper 		request.area = create_area("publish inputs", &start_addr, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
4043620737cSbeveloper 		if (request.area < B_OK) {
4055ac4fbd7Sbeveloper 			ERROR("PublishInputs: failed to create area, %#lx\n", request.area);
4063620737cSbeveloper 			return (status_t)request.area;
4073620737cSbeveloper 		}
4083620737cSbeveloper 		inputs = static_cast<media_input *>(start_addr);
4093620737cSbeveloper 	} else {
4103620737cSbeveloper 		request.area = -1;
4113620737cSbeveloper 		inputs = request.inputs;
4123620737cSbeveloper 	}
41376669a29Sbeveloper 	TRACE("PublishInputs: area %ld\n", request.area);
4143620737cSbeveloper 
41576669a29Sbeveloper 	int i;
41676669a29Sbeveloper 	for (i = 0, list->Rewind(); list->GetNext(&input); i++) {
41776669a29Sbeveloper 		ASSERT(i < count);
4183620737cSbeveloper 		inputs[i] = *input;
4193620737cSbeveloper 	}
4203620737cSbeveloper 
421a7b41a96Sbeveloper 	rv = QueryServer(SERVER_PUBLISH_INPUTS, &request, sizeof(request), &reply, sizeof(reply));
422a7b41a96Sbeveloper 
423a7b41a96Sbeveloper 	if (request.area != -1)
424a7b41a96Sbeveloper 		delete_area(request.area);
425a7b41a96Sbeveloper 
426a7b41a96Sbeveloper 	return rv;
4273620737cSbeveloper }
4283620737cSbeveloper 
42952a38012Sejakowatz /*************************************************************
43052a38012Sejakowatz  * public BMediaRoster
43152a38012Sejakowatz  *************************************************************/
43252a38012Sejakowatz 
43352a38012Sejakowatz status_t
43452a38012Sejakowatz BMediaRoster::GetVideoInput(media_node * out_node)
43552a38012Sejakowatz {
43652a38012Sejakowatz 	CALLED();
4378b04ffc1Sbeveloper 	return MediaRosterEx(this)->GetNode(VIDEO_INPUT, out_node);
43852a38012Sejakowatz }
43952a38012Sejakowatz 
44052a38012Sejakowatz 
44152a38012Sejakowatz status_t
44252a38012Sejakowatz BMediaRoster::GetAudioInput(media_node * out_node)
44352a38012Sejakowatz {
44452a38012Sejakowatz 	CALLED();
4458b04ffc1Sbeveloper 	return MediaRosterEx(this)->GetNode(AUDIO_INPUT, out_node);
44652a38012Sejakowatz }
44752a38012Sejakowatz 
44852a38012Sejakowatz 
44952a38012Sejakowatz status_t
45052a38012Sejakowatz BMediaRoster::GetVideoOutput(media_node * out_node)
45152a38012Sejakowatz {
45252a38012Sejakowatz 	CALLED();
4538b04ffc1Sbeveloper 	return MediaRosterEx(this)->GetNode(VIDEO_OUTPUT, out_node);
45452a38012Sejakowatz }
45552a38012Sejakowatz 
45652a38012Sejakowatz 
45752a38012Sejakowatz status_t
45852a38012Sejakowatz BMediaRoster::GetAudioMixer(media_node * out_node)
45952a38012Sejakowatz {
46052a38012Sejakowatz 	CALLED();
4618b04ffc1Sbeveloper 	return MediaRosterEx(this)->GetNode(AUDIO_MIXER, out_node);
46252a38012Sejakowatz }
46352a38012Sejakowatz 
46452a38012Sejakowatz 
46552a38012Sejakowatz status_t
46652a38012Sejakowatz BMediaRoster::GetAudioOutput(media_node * out_node)
46752a38012Sejakowatz {
46852a38012Sejakowatz 	CALLED();
4698b04ffc1Sbeveloper 	return MediaRosterEx(this)->GetNode(AUDIO_OUTPUT, out_node);
47052a38012Sejakowatz }
47152a38012Sejakowatz 
47252a38012Sejakowatz 
47352a38012Sejakowatz status_t
47452a38012Sejakowatz BMediaRoster::GetAudioOutput(media_node * out_node,
47552a38012Sejakowatz 							 int32 * out_input_id,
47652a38012Sejakowatz 							 BString * out_input_name)
47752a38012Sejakowatz {
47852a38012Sejakowatz 	CALLED();
4798b04ffc1Sbeveloper 	return MediaRosterEx(this)->GetNode(AUDIO_OUTPUT_EX, out_node, out_input_id, out_input_name);
48052a38012Sejakowatz }
48152a38012Sejakowatz 
48252a38012Sejakowatz 
48352a38012Sejakowatz status_t
48452a38012Sejakowatz BMediaRoster::GetTimeSource(media_node * out_node)
48552a38012Sejakowatz {
48652a38012Sejakowatz 	CALLED();
48786bce45bSbeveloper 	status_t rv;
48886bce45bSbeveloper 
48986bce45bSbeveloper 	// XXX need to do this in a nicer way.
49086bce45bSbeveloper 
49186bce45bSbeveloper 	rv = MediaRosterEx(this)->GetNode(TIME_SOURCE, out_node);
49286bce45bSbeveloper 	if (rv != B_OK)
49386bce45bSbeveloper 		return rv;
49486bce45bSbeveloper 
49586bce45bSbeveloper 	// We don't do reference counting for timesources, that's why we
49686bce45bSbeveloper 	// release the node immediately.
49786bce45bSbeveloper 	ReleaseNode(*out_node);
49886bce45bSbeveloper 
49986bce45bSbeveloper 	// we need to remember to not use this node with server side reference counting
50086bce45bSbeveloper 	out_node->kind |= NODE_KIND_NO_REFCOUNTING;
50186bce45bSbeveloper 
50286bce45bSbeveloper 	return B_OK;
50352a38012Sejakowatz }
50452a38012Sejakowatz 
50552a38012Sejakowatz 
50652a38012Sejakowatz status_t
50752a38012Sejakowatz BMediaRoster::SetVideoInput(const media_node & producer)
50852a38012Sejakowatz {
50952a38012Sejakowatz 	CALLED();
5108b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_INPUT, &producer);
51152a38012Sejakowatz }
51252a38012Sejakowatz 
51352a38012Sejakowatz 
51452a38012Sejakowatz status_t
51552a38012Sejakowatz BMediaRoster::SetVideoInput(const dormant_node_info & producer)
51652a38012Sejakowatz {
51752a38012Sejakowatz 	CALLED();
5188b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_INPUT, NULL, &producer);
51952a38012Sejakowatz }
52052a38012Sejakowatz 
52152a38012Sejakowatz 
52252a38012Sejakowatz status_t
52352a38012Sejakowatz BMediaRoster::SetAudioInput(const media_node & producer)
52452a38012Sejakowatz {
52552a38012Sejakowatz 	CALLED();
5268b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_INPUT, &producer);
52752a38012Sejakowatz }
52852a38012Sejakowatz 
52952a38012Sejakowatz 
53052a38012Sejakowatz status_t
53152a38012Sejakowatz BMediaRoster::SetAudioInput(const dormant_node_info & producer)
53252a38012Sejakowatz {
53352a38012Sejakowatz 	CALLED();
5348b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_INPUT, NULL, &producer);
53552a38012Sejakowatz }
53652a38012Sejakowatz 
53752a38012Sejakowatz 
53852a38012Sejakowatz status_t
53952a38012Sejakowatz BMediaRoster::SetVideoOutput(const media_node & consumer)
54052a38012Sejakowatz {
54152a38012Sejakowatz 	CALLED();
5428b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_OUTPUT, &consumer);
54352a38012Sejakowatz }
54452a38012Sejakowatz 
54552a38012Sejakowatz 
54652a38012Sejakowatz status_t
54752a38012Sejakowatz BMediaRoster::SetVideoOutput(const dormant_node_info & consumer)
54852a38012Sejakowatz {
54952a38012Sejakowatz 	CALLED();
5508b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_OUTPUT, NULL, &consumer);
55152a38012Sejakowatz }
55252a38012Sejakowatz 
55352a38012Sejakowatz 
55452a38012Sejakowatz status_t
55552a38012Sejakowatz BMediaRoster::SetAudioOutput(const media_node & consumer)
55652a38012Sejakowatz {
55752a38012Sejakowatz 	CALLED();
5588b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, &consumer);
55952a38012Sejakowatz }
56052a38012Sejakowatz 
56152a38012Sejakowatz 
56252a38012Sejakowatz status_t
56352a38012Sejakowatz BMediaRoster::SetAudioOutput(const media_input & input_to_output)
56452a38012Sejakowatz {
56552a38012Sejakowatz 	CALLED();
5668b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, NULL, NULL, &input_to_output);
56752a38012Sejakowatz }
56852a38012Sejakowatz 
56952a38012Sejakowatz 
57052a38012Sejakowatz status_t
57152a38012Sejakowatz BMediaRoster::SetAudioOutput(const dormant_node_info & consumer)
57252a38012Sejakowatz {
57352a38012Sejakowatz 	CALLED();
5748b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, NULL, &consumer);
57552a38012Sejakowatz }
57652a38012Sejakowatz 
57752a38012Sejakowatz 
57852a38012Sejakowatz status_t
57952a38012Sejakowatz BMediaRoster::GetNodeFor(media_node_id node,
58052a38012Sejakowatz 						 media_node * clone)
58152a38012Sejakowatz {
5829e9417d2Sbeveloper 	CALLED();
5839e9417d2Sbeveloper 	if (clone == NULL)
5849e9417d2Sbeveloper 		return B_BAD_VALUE;
58565b73ae4SMarcus Overhagen 	if (IS_INVALID_NODEID(node))
5869e9417d2Sbeveloper 		return B_MEDIA_BAD_NODE;
5879e9417d2Sbeveloper 
5889e9417d2Sbeveloper 	server_get_node_for_request request;
5899e9417d2Sbeveloper 	server_get_node_for_reply reply;
5909e9417d2Sbeveloper 	status_t rv;
5919e9417d2Sbeveloper 
5929e9417d2Sbeveloper 	request.nodeid = node;
5939e9417d2Sbeveloper 	request.team = team;
5949e9417d2Sbeveloper 
5959e9417d2Sbeveloper 	rv = QueryServer(SERVER_GET_NODE_FOR, &request, sizeof(request), &reply, sizeof(reply));
5969e9417d2Sbeveloper 	if (rv != B_OK)
5979e9417d2Sbeveloper 		return rv;
5989e9417d2Sbeveloper 
5999e9417d2Sbeveloper 	*clone = reply.clone;
6009e9417d2Sbeveloper 	return B_OK;
60152a38012Sejakowatz }
60252a38012Sejakowatz 
60352a38012Sejakowatz 
60452a38012Sejakowatz status_t
60552a38012Sejakowatz BMediaRoster::GetSystemTimeSource(media_node * clone)
60652a38012Sejakowatz {
60752a38012Sejakowatz 	CALLED();
60886bce45bSbeveloper 	status_t rv;
60986bce45bSbeveloper 
61086bce45bSbeveloper 	// XXX need to do this in a nicer way.
61186bce45bSbeveloper 
61286bce45bSbeveloper 	rv = MediaRosterEx(this)->GetNode(SYSTEM_TIME_SOURCE, clone);
61386bce45bSbeveloper 	if (rv != B_OK)
61486bce45bSbeveloper 		return rv;
61586bce45bSbeveloper 
61686bce45bSbeveloper 	// We don't do reference counting for timesources, that's why we
61786bce45bSbeveloper 	// release the node immediately.
61886bce45bSbeveloper 	ReleaseNode(*clone);
61986bce45bSbeveloper 
62086bce45bSbeveloper 	// we need to remember to not use this node with server side reference counting
62186bce45bSbeveloper 	clone->kind |= NODE_KIND_NO_REFCOUNTING;
62286bce45bSbeveloper 
62386bce45bSbeveloper 	return B_OK;
62452a38012Sejakowatz }
62552a38012Sejakowatz 
62652a38012Sejakowatz 
62752a38012Sejakowatz status_t
62852a38012Sejakowatz BMediaRoster::ReleaseNode(const media_node & node)
62952a38012Sejakowatz {
6309e9417d2Sbeveloper 	CALLED();
63140f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
6329e9417d2Sbeveloper 		return B_MEDIA_BAD_NODE;
63352a38012Sejakowatz 
63486bce45bSbeveloper 	if (node.kind & NODE_KIND_NO_REFCOUNTING) {
63586bce45bSbeveloper 		printf("BMediaRoster::ReleaseNode, trying to release reference counting disabled timesource, node %ld, port %ld, team %ld\n", node.node, node.port, team);
63686bce45bSbeveloper 		return B_OK;
63786bce45bSbeveloper 	}
63886bce45bSbeveloper 
6399e9417d2Sbeveloper 	server_release_node_request request;
6409e9417d2Sbeveloper 	server_release_node_reply reply;
641cf4e2277Sbeveloper 	status_t rv;
6429e9417d2Sbeveloper 
6439e9417d2Sbeveloper 	request.node = node;
6449e9417d2Sbeveloper 	request.team = team;
6459e9417d2Sbeveloper 
64660f15390Sbeveloper 	TRACE("BMediaRoster::ReleaseNode, node %ld, port %ld, team %ld\n", node.node, node.port, team);
647cf4e2277Sbeveloper 
648cf4e2277Sbeveloper 	rv = QueryServer(SERVER_RELEASE_NODE, &request, sizeof(request), &reply, sizeof(reply));
649cf4e2277Sbeveloper 	if (rv != B_OK) {
6505ac4fbd7Sbeveloper 		ERROR("BMediaRoster::ReleaseNode FAILED, node %ld, port %ld, team %ld!\n", node.node, node.port, team);
651cf4e2277Sbeveloper 	}
652cf4e2277Sbeveloper 	return rv;
6539e9417d2Sbeveloper }
65452a38012Sejakowatz 
65552a38012Sejakowatz BTimeSource *
65652a38012Sejakowatz BMediaRoster::MakeTimeSourceFor(const media_node & for_node)
65752a38012Sejakowatz {
658f180ef79Sbeveloper 	// MakeTimeSourceFor() returns a BTimeSource object
659f180ef79Sbeveloper 	// corresponding to the specified node's time source.
660f180ef79Sbeveloper 
661835140c8Sbeveloper 	CALLED();
662f180ef79Sbeveloper 
66392e575c1Sbeveloper 	if (IS_SYSTEM_TIMESOURCE(for_node)) {
664f180ef79Sbeveloper 		// special handling for the system time source
665f180ef79Sbeveloper 		TRACE("BMediaRoster::MakeTimeSourceFor, asked for system time source\n");
666f180ef79Sbeveloper 		return MediaRosterEx(this)->MakeTimeSourceObject(NODE_SYSTEM_TIMESOURCE_ID);
667f180ef79Sbeveloper 	}
668f180ef79Sbeveloper 
6695917dd5bSbeveloper 	if (IS_INVALID_NODE(for_node)) {
6705ac4fbd7Sbeveloper 		ERROR("BMediaRoster::MakeTimeSourceFor: for_node invalid, node %ld, port %ld, kinds 0x%lx\n", for_node.node, for_node.port, for_node.kind);
6715917dd5bSbeveloper 		return NULL;
6720e21b167Sbeveloper 	}
6730e21b167Sbeveloper 
674f180ef79Sbeveloper 	TRACE("BMediaRoster::MakeTimeSourceFor: node %ld enter\n", for_node.node);
6755917dd5bSbeveloper 
6765917dd5bSbeveloper 	node_get_timesource_request request;
6775917dd5bSbeveloper 	node_get_timesource_reply reply;
6785917dd5bSbeveloper 	BTimeSource *source;
6795917dd5bSbeveloper 	status_t rv;
6805917dd5bSbeveloper 
68192e575c1Sbeveloper 	// ask the node to get it's current timesource id
6825917dd5bSbeveloper 	rv = QueryPort(for_node.port, NODE_GET_TIMESOURCE, &request, sizeof(request), &reply, sizeof(reply));
6835917dd5bSbeveloper 	if (rv != B_OK) {
6845ac4fbd7Sbeveloper 		ERROR("BMediaRoster::MakeTimeSourceFor: request failed\n");
6855917dd5bSbeveloper 		return NULL;
6865917dd5bSbeveloper 	}
6875917dd5bSbeveloper 
6885917dd5bSbeveloper 	source = MediaRosterEx(this)->MakeTimeSourceObject(reply.timesource_id);
6895917dd5bSbeveloper 
690f180ef79Sbeveloper 	TRACE("BMediaRoster::MakeTimeSourceFor: node %ld leave\n", for_node.node);
6915917dd5bSbeveloper 
6925917dd5bSbeveloper 	return source;
6935917dd5bSbeveloper }
6945917dd5bSbeveloper 
6955917dd5bSbeveloper BTimeSource *
6965917dd5bSbeveloper BMediaRosterEx::MakeTimeSourceObject(media_node_id timesource_id)
6975917dd5bSbeveloper {
6985917dd5bSbeveloper 	BTimeSource *source;
6995917dd5bSbeveloper 	media_node clone;
7005917dd5bSbeveloper 	status_t rv;
7015917dd5bSbeveloper 
7025917dd5bSbeveloper 	rv = GetNodeFor(timesource_id, &clone);
7035917dd5bSbeveloper 	if (rv != B_OK) {
7045ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::MakeTimeSourceObject: GetNodeFor failed\n");
7055917dd5bSbeveloper 		return NULL;
7065917dd5bSbeveloper 	}
7075917dd5bSbeveloper 
7085917dd5bSbeveloper 	source = _TimeSourceObjectManager->GetTimeSource(clone);
7095917dd5bSbeveloper 	if (source == NULL) {
7105ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::MakeTimeSourceObject: GetTimeSource failed\n");
7115917dd5bSbeveloper 		return NULL;
7125917dd5bSbeveloper 	}
7135917dd5bSbeveloper 
71492e575c1Sbeveloper 	// XXX release?
71592e575c1Sbeveloper 	ReleaseNode(clone);
716287f7492Sbeveloper 
717835140c8Sbeveloper 	return source;
71852a38012Sejakowatz }
71952a38012Sejakowatz 
72052a38012Sejakowatz 
72152a38012Sejakowatz status_t
72252a38012Sejakowatz BMediaRoster::Connect(const media_source & from,
72352a38012Sejakowatz 					  const media_destination & to,
72452a38012Sejakowatz 					  media_format * io_format,
72552a38012Sejakowatz 					  media_output * out_output,
72652a38012Sejakowatz 					  media_input * out_input)
72752a38012Sejakowatz {
728eae26d3dSbeveloper 	return BMediaRoster::Connect(from, to, io_format, out_output, out_input, 0);
729eae26d3dSbeveloper }
730eae26d3dSbeveloper 
731eae26d3dSbeveloper 
732eae26d3dSbeveloper status_t
733eae26d3dSbeveloper BMediaRoster::Connect(const media_source & from,
734eae26d3dSbeveloper 					  const media_destination & to,
735eae26d3dSbeveloper 					  media_format * io_format,
736eae26d3dSbeveloper 					  media_output * out_output,
737eae26d3dSbeveloper 					  media_input * out_input,
738eae26d3dSbeveloper 					  uint32 in_flags,
739eae26d3dSbeveloper 					  void * _reserved)
740eae26d3dSbeveloper {
74152a38012Sejakowatz 	CALLED();
74252a38012Sejakowatz 	if (io_format == NULL || out_output == NULL || out_input == NULL)
74352a38012Sejakowatz 		return B_BAD_VALUE;
74440f36b03Sbeveloper 	if (IS_INVALID_SOURCE(from)) {
7455ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: media_source invalid\n");
74652a38012Sejakowatz 		return B_MEDIA_BAD_SOURCE;
7479e9417d2Sbeveloper 	}
74840f36b03Sbeveloper 	if (IS_INVALID_DESTINATION(to)) {
7495ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: media_destination invalid\n");
75052a38012Sejakowatz 		return B_MEDIA_BAD_DESTINATION;
7519e9417d2Sbeveloper 	}
75252a38012Sejakowatz 
75352a38012Sejakowatz 	status_t rv;
75465b73ae4SMarcus Overhagen 
75565b73ae4SMarcus Overhagen 	// find the output and input nodes
75665b73ae4SMarcus Overhagen 	// XXX isn't there a easier way?
75765b73ae4SMarcus Overhagen 	media_node sourcenode;
75865b73ae4SMarcus Overhagen 	media_node destnode;
75965b73ae4SMarcus Overhagen 	rv = GetNodeFor(NodeIDFor(from.port), &sourcenode);
76065b73ae4SMarcus Overhagen 	if (rv != B_OK) {
76165b73ae4SMarcus Overhagen 		ERROR("BMediaRoster::Connect: Can't find source node for port %ld\n", from.port);
76265b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
76365b73ae4SMarcus Overhagen 	}
76465b73ae4SMarcus Overhagen 	ReleaseNode(sourcenode);
76565b73ae4SMarcus Overhagen 	rv = GetNodeFor(NodeIDFor(to.port), &destnode);
76665b73ae4SMarcus Overhagen 	if (rv != B_OK) {
76765b73ae4SMarcus Overhagen 		ERROR("BMediaRoster::Connect: Can't find destination node for port %ld\n", to.port);
76865b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
76965b73ae4SMarcus Overhagen 	}
77065b73ae4SMarcus Overhagen 	ReleaseNode(destnode);
77165b73ae4SMarcus Overhagen 
77265b73ae4SMarcus Overhagen 	if (!(sourcenode.kind & B_BUFFER_PRODUCER)) {
77365b73ae4SMarcus Overhagen 		ERROR("BMediaRoster::Connect: source node %ld is not a B_BUFFER_PRODUCER\n", sourcenode.node);
77465b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
77565b73ae4SMarcus Overhagen 	}
77665b73ae4SMarcus Overhagen 	if (!(destnode.kind & B_BUFFER_CONSUMER)) {
77765b73ae4SMarcus Overhagen 		ERROR("BMediaRoster::Connect: destination node %ld is not a B_BUFFER_CONSUMER\n", destnode.node);
77865b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
77965b73ae4SMarcus Overhagen 	}
78065b73ae4SMarcus Overhagen 
7818c6a6096Sbeveloper 	producer_format_proposal_request request1;
7828c6a6096Sbeveloper 	producer_format_proposal_reply reply1;
78352a38012Sejakowatz 
78469983609Sbeveloper 	PRINT_FORMAT("BMediaRoster::Connect calling BBufferProducer::FormatProposal with format  ", *io_format);
78569983609Sbeveloper 
78652a38012Sejakowatz 	// BBufferProducer::FormatProposal
7878c6a6096Sbeveloper 	request1.output = from;
7888c6a6096Sbeveloper 	request1.format = *io_format;
7898c6a6096Sbeveloper 	rv = QueryPort(from.port, PRODUCER_FORMAT_PROPOSAL, &request1, sizeof(request1), &reply1, sizeof(reply1));
7908c6a6096Sbeveloper 	if (rv != B_OK) {
7915ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: aborted after BBufferProducer::FormatProposal, status = %#lx\n",rv);
79252a38012Sejakowatz 		return rv;
79352a38012Sejakowatz 	}
7948c6a6096Sbeveloper 	// reply1.format now contains the format proposed by the producer
7958c6a6096Sbeveloper 
7968c6a6096Sbeveloper 	consumer_accept_format_request request2;
7978c6a6096Sbeveloper 	consumer_accept_format_reply reply2;
7988c6a6096Sbeveloper 
79969983609Sbeveloper 	PRINT_FORMAT("BMediaRoster::Connect calling BBufferConsumer::AcceptFormat with format    ", reply1.format);
80069983609Sbeveloper 
8018c6a6096Sbeveloper 	// BBufferConsumer::AcceptFormat
8028c6a6096Sbeveloper 	request2.dest = to;
8038c6a6096Sbeveloper 	request2.format = reply1.format;
8048c6a6096Sbeveloper 	rv = QueryPort(to.port, CONSUMER_ACCEPT_FORMAT, &request2, sizeof(request2), &reply2, sizeof(reply2));
8058c6a6096Sbeveloper 	if (rv != B_OK) {
8065ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: aborted after BBufferConsumer::AcceptFormat, status = %#lx\n",rv);
8078c6a6096Sbeveloper 		return rv;
8088c6a6096Sbeveloper 	}
8098c6a6096Sbeveloper 	// reply2.format now contains the format accepted by the consumer
8108c6a6096Sbeveloper 
8118c6a6096Sbeveloper 	// BBufferProducer::PrepareToConnect
8128c6a6096Sbeveloper 	producer_prepare_to_connect_request request3;
8138c6a6096Sbeveloper 	producer_prepare_to_connect_reply reply3;
8148c6a6096Sbeveloper 
81569983609Sbeveloper 	PRINT_FORMAT("BMediaRoster::Connect calling BBufferProducer::PrepareToConnect with format", reply2.format);
81669983609Sbeveloper 
8178c6a6096Sbeveloper 	request3.source = from;
8188c6a6096Sbeveloper 	request3.destination = to;
8198c6a6096Sbeveloper 	request3.format = reply2.format;
8208c6a6096Sbeveloper 	strcpy(request3.name, "XXX some default name"); // XXX fix this
8218c6a6096Sbeveloper 	rv = QueryPort(from.port, PRODUCER_PREPARE_TO_CONNECT, &request3, sizeof(request3), &reply3, sizeof(reply3));
8228c6a6096Sbeveloper 	if (rv != B_OK) {
8235ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: aborted after BBufferProducer::PrepareToConnect, status = %#lx\n",rv);
8248c6a6096Sbeveloper 		return rv;
8258c6a6096Sbeveloper 	}
8268c6a6096Sbeveloper 	// reply3.format is still our pretty media format
8278c6a6096Sbeveloper 	// reply3.out_source the real source to be used for the connection
8288c6a6096Sbeveloper 	// reply3.name the name BBufferConsumer::Connected will see in the outInput->name argument
8298c6a6096Sbeveloper 
8308c6a6096Sbeveloper 	// BBufferConsumer::Connected
8318c6a6096Sbeveloper 	consumer_connected_request request4;
8328c6a6096Sbeveloper 	consumer_connected_reply reply4;
8338c6a6096Sbeveloper 	status_t con_status;
8348c6a6096Sbeveloper 
83569983609Sbeveloper 	PRINT_FORMAT("BMediaRoster::Connect calling BBufferConsumer::Connected with format       ", reply3.format);
83669983609Sbeveloper 
83769983609Sbeveloper 	request4.input.node = destnode;
83869983609Sbeveloper 	request4.input.source = reply3.out_source;
83969983609Sbeveloper 	request4.input.destination = to;
84069983609Sbeveloper 	request4.input.format = reply3.format;
84169983609Sbeveloper 	strcpy(request4.input.name, reply3.name);
84269983609Sbeveloper 
8438c6a6096Sbeveloper 	con_status = QueryPort(to.port, CONSUMER_CONNECTED, &request4, sizeof(request4), &reply4, sizeof(reply4));
8448c6a6096Sbeveloper 	if (con_status != B_OK) {
8455ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: aborting after BBufferConsumer::Connected, status = %#lx\n",con_status);
8468c6a6096Sbeveloper 		// we do NOT return here!
8478c6a6096Sbeveloper 	}
8488c6a6096Sbeveloper 	// con_status contains the status code to be supplied to BBufferProducer::Connect's status argument
8498c6a6096Sbeveloper 	// reply4.input contains the media_input that describes the connection from the consumer point of view
8508c6a6096Sbeveloper 
8518c6a6096Sbeveloper 	// BBufferProducer::Connect
8528c6a6096Sbeveloper 	producer_connect_request request5;
8538c6a6096Sbeveloper 	producer_connect_reply reply5;
8548c6a6096Sbeveloper 
85569983609Sbeveloper 	PRINT_FORMAT("BMediaRoster::Connect calling BBufferProducer::Connect with format         ", reply4.input.format);
85669983609Sbeveloper 
8578c6a6096Sbeveloper 	request5.error = con_status;
8588c6a6096Sbeveloper 	request5.source = reply3.out_source;
8598c6a6096Sbeveloper 	request5.destination = reply4.input.destination;
86069983609Sbeveloper 	request5.format = reply4.input.format;
8618c6a6096Sbeveloper 	strcpy(request5.name, reply4.input.name);
8620caff283Sbeveloper 	rv = QueryPort(reply4.input.source.port, PRODUCER_CONNECT, &request5, sizeof(request5), &reply5, sizeof(reply5));
8638c6a6096Sbeveloper 	if (con_status != B_OK) {
8645ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: aborted\n");
8658c6a6096Sbeveloper 		return con_status;
8668c6a6096Sbeveloper 	}
8678c6a6096Sbeveloper 	if (rv != B_OK) {
8685ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: aborted after BBufferProducer::Connect, status = %#lx\n",rv);
8698c6a6096Sbeveloper 		return rv;
8708c6a6096Sbeveloper 	}
8718c6a6096Sbeveloper 	// reply5.name contains the name assigned to the connection by the producer
8728c6a6096Sbeveloper 
8738c6a6096Sbeveloper 	// initilize connection info
87469983609Sbeveloper 	*io_format = reply4.input.format;
8758c6a6096Sbeveloper 	*out_input = reply4.input;
8768c6a6096Sbeveloper 	out_output->node = sourcenode;
8778c6a6096Sbeveloper 	out_output->source = reply4.input.source;
8788c6a6096Sbeveloper 	out_output->destination = reply4.input.destination;
8798c6a6096Sbeveloper 	out_output->format = reply4.input.format;
8808c6a6096Sbeveloper 	strcpy(out_output->name, reply5.name);
8818c6a6096Sbeveloper 
8828c6a6096Sbeveloper 	// the connection is now made
88369983609Sbeveloper 	printf("BMediaRoster::Connect connection established!\n");
88469983609Sbeveloper 	PRINT_FORMAT("   format", *io_format);
88569983609Sbeveloper 	PRINT_INPUT("   input", *out_input);
88669983609Sbeveloper 	PRINT_OUTPUT("   output", *out_output);
8878c6a6096Sbeveloper 
8888c6a6096Sbeveloper 	// XXX register connection with server
8899e9417d2Sbeveloper 	// XXX we should just send a notification, instead of republishing all endpoints
89076669a29Sbeveloper 	List<media_output> outlist;
89176669a29Sbeveloper 	List<media_input> inlist;
8928b04ffc1Sbeveloper 	if (B_OK == MediaRosterEx(this)->GetAllOutputs(out_output->node , &outlist))
8938b04ffc1Sbeveloper 		MediaRosterEx(this)->PublishOutputs(out_output->node , &outlist);
8948b04ffc1Sbeveloper 	if (B_OK == MediaRosterEx(this)->GetAllInputs(out_input->node , &inlist))
8958b04ffc1Sbeveloper 		MediaRosterEx(this)->PublishInputs(out_input->node, &inlist);
8968c6a6096Sbeveloper 
8978c6a6096Sbeveloper 
8988c6a6096Sbeveloper 	// XXX if (mute) BBufferProducer::EnableOutput(false)
8999e9417d2Sbeveloper 	if (in_flags & B_CONNECT_MUTED) {
9009e9417d2Sbeveloper 	}
9018c6a6096Sbeveloper 
9028c6a6096Sbeveloper 
9039e9417d2Sbeveloper 	// send a notification
9049e9417d2Sbeveloper 	BPrivate::media::notifications::ConnectionMade(*out_input, *out_output, *io_format);
9059e9417d2Sbeveloper 
9068c6a6096Sbeveloper 	return B_OK;
9078c6a6096Sbeveloper };
90852a38012Sejakowatz 
90952a38012Sejakowatz 
91052a38012Sejakowatz status_t
9119e9417d2Sbeveloper BMediaRoster::Disconnect(media_node_id source_nodeid,
91252a38012Sejakowatz 						 const media_source & source,
9139e9417d2Sbeveloper 						 media_node_id destination_nodeid,
91452a38012Sejakowatz 						 const media_destination & destination)
91552a38012Sejakowatz {
9169e9417d2Sbeveloper 	CALLED();
91740f36b03Sbeveloper 	if (IS_INVALID_NODEID(source_nodeid)) {
9185ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: source media_node_id invalid\n");
9199e9417d2Sbeveloper 		return B_MEDIA_BAD_SOURCE;
9209e9417d2Sbeveloper 	}
92140f36b03Sbeveloper 	if (IS_INVALID_NODEID(destination_nodeid)) {
9225ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: destination media_node_id invalid\n");
9239e9417d2Sbeveloper 		return B_MEDIA_BAD_DESTINATION;
9249e9417d2Sbeveloper 	}
92540f36b03Sbeveloper 	if (IS_INVALID_SOURCE(source)) {
9265ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: media_source invalid\n");
9279e9417d2Sbeveloper 		return B_MEDIA_BAD_SOURCE;
9289e9417d2Sbeveloper 	}
92940f36b03Sbeveloper 	if (IS_INVALID_DESTINATION(destination)) {
9305ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: media_destination invalid\n");
9319e9417d2Sbeveloper 		return B_MEDIA_BAD_DESTINATION;
9329e9417d2Sbeveloper 	}
9339e9417d2Sbeveloper 
9349e9417d2Sbeveloper 	producer_disconnect_request request2;
9359e9417d2Sbeveloper 	producer_disconnect_reply reply2;
9369e9417d2Sbeveloper 	consumer_disconnected_request request1;
9379e9417d2Sbeveloper 	consumer_disconnected_reply reply1;
9389e9417d2Sbeveloper 	status_t rv1, rv2;
9399e9417d2Sbeveloper 
9409e9417d2Sbeveloper 	// XXX we should ask the server if this connection really exists
9419e9417d2Sbeveloper 
9429e9417d2Sbeveloper 	request1.source = source;
9439e9417d2Sbeveloper 	request1.destination = destination;
9449e9417d2Sbeveloper 	request2.source = source;
9459e9417d2Sbeveloper 	request2.destination = destination;
9469e9417d2Sbeveloper 
9479e9417d2Sbeveloper 	rv1 = QueryPort(source.port, PRODUCER_DISCONNECT, &request1, sizeof(request1), &reply1, sizeof(reply1));
9489e9417d2Sbeveloper 	rv2 = QueryPort(destination.port, CONSUMER_DISCONNECTED, &request2, sizeof(request2), &reply2, sizeof(reply2));
9499e9417d2Sbeveloper 
9509e9417d2Sbeveloper 	// XXX unregister connection with server
9519e9417d2Sbeveloper 	// XXX we should just send a notification, instead of republishing all endpoints
95276669a29Sbeveloper 	List<media_output> outlist;
95376669a29Sbeveloper 	List<media_input> inlist;
9549e9417d2Sbeveloper 	media_node sourcenode;
9559e9417d2Sbeveloper 	media_node destnode;
9569e9417d2Sbeveloper 	if (B_OK == GetNodeFor(source_nodeid, &sourcenode)) {
95765b73ae4SMarcus Overhagen 		if (!(sourcenode.kind & B_BUFFER_PRODUCER)) {
95865b73ae4SMarcus Overhagen 			ERROR("BMediaRoster::Disconnect: source_nodeid %ld is not a B_BUFFER_PRODUCER\n", source_nodeid);
95965b73ae4SMarcus Overhagen 		}
9608b04ffc1Sbeveloper 		if (B_OK == MediaRosterEx(this)->GetAllOutputs(sourcenode , &outlist))
9618b04ffc1Sbeveloper 			MediaRosterEx(this)->PublishOutputs(sourcenode , &outlist);
9629e9417d2Sbeveloper 		ReleaseNode(sourcenode);
9634f09fa2fSbeveloper 	} else {
96465b73ae4SMarcus Overhagen 		ERROR("BMediaRoster::Disconnect: GetNodeFor source_nodeid %ld failed\n", source_nodeid);
9654f09fa2fSbeveloper 	}
9669e9417d2Sbeveloper 	if (B_OK == GetNodeFor(destination_nodeid, &destnode)) {
96765b73ae4SMarcus Overhagen 		if (!(destnode.kind & B_BUFFER_CONSUMER)) {
96865b73ae4SMarcus Overhagen 			ERROR("BMediaRoster::Disconnect: destination_nodeid %ld is not a B_BUFFER_CONSUMER\n", destination_nodeid);
96965b73ae4SMarcus Overhagen 		}
9708b04ffc1Sbeveloper 		if (B_OK == MediaRosterEx(this)->GetAllInputs(destnode , &inlist))
9718b04ffc1Sbeveloper 			MediaRosterEx(this)->PublishInputs(destnode, &inlist);
9729e9417d2Sbeveloper 		ReleaseNode(destnode);
9734f09fa2fSbeveloper 	} else {
97465b73ae4SMarcus Overhagen 		ERROR("BMediaRoster::Disconnect: GetNodeFor destination_nodeid %ld failed\n", destination_nodeid);
9754f09fa2fSbeveloper 	}
9769e9417d2Sbeveloper 
9779e9417d2Sbeveloper 
9789e9417d2Sbeveloper 	// send a notification
9799e9417d2Sbeveloper 	BPrivate::media::notifications::ConnectionBroken(source, destination);
9809e9417d2Sbeveloper 
9819e9417d2Sbeveloper 	return (rv1 != B_OK || rv2 != B_OK) ? B_ERROR : B_OK;
98252a38012Sejakowatz }
98352a38012Sejakowatz 
98465b73ae4SMarcus Overhagen status_t
98565b73ae4SMarcus Overhagen BMediaRoster::Disconnect(const media_output &output, const media_input &input)
98665b73ae4SMarcus Overhagen {
98765b73ae4SMarcus Overhagen 	if (IS_INVALID_NODEID(output.node.node)) {
98865b73ae4SMarcus Overhagen 		printf("BMediaRoster::Disconnect: output.node.node %ld invalid\n",
98965b73ae4SMarcus Overhagen 			output.node.node);
99065b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
99165b73ae4SMarcus Overhagen 	}
99265b73ae4SMarcus Overhagen 	if (IS_INVALID_NODEID(input.node.node)) {
99365b73ae4SMarcus Overhagen 		printf("BMediaRoster::Disconnect: input.node.node %ld invalid\n",
99465b73ae4SMarcus Overhagen 			input.node.node);
99565b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
99665b73ae4SMarcus Overhagen 	}
99765b73ae4SMarcus Overhagen 	if (!(output.node.kind & B_BUFFER_PRODUCER)) {
99865b73ae4SMarcus Overhagen 		printf("BMediaRoster::Disconnect: output.node.kind 0x%lx is no B_BUFFER_PRODUCER\n",
99965b73ae4SMarcus Overhagen 			output.node.kind);
100065b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
100165b73ae4SMarcus Overhagen 	}
100265b73ae4SMarcus Overhagen 	if (!(input.node.kind & B_BUFFER_CONSUMER)) {
100365b73ae4SMarcus Overhagen 		printf("BMediaRoster::Disconnect: input.node.kind 0x%lx is no B_BUFFER_PRODUCER\n",
100465b73ae4SMarcus Overhagen 			input.node.kind);
100565b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
100665b73ae4SMarcus Overhagen 	}
100765b73ae4SMarcus Overhagen 	if (input.source.port != output.source.port) {
100865b73ae4SMarcus Overhagen 		printf("BMediaRoster::Disconnect: input.source.port %ld doesn't match output.source.port %ld\n",
100965b73ae4SMarcus Overhagen 			input.source.port, output.source.port);
101065b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
101165b73ae4SMarcus Overhagen 	}
101265b73ae4SMarcus Overhagen 	if (input.source.id != output.source.id) {
101365b73ae4SMarcus Overhagen 		printf("BMediaRoster::Disconnect: input.source.id %ld doesn't match output.source.id %ld\n",
101465b73ae4SMarcus Overhagen 			input.source.id, output.source.id);
101565b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
101665b73ae4SMarcus Overhagen 	}
101765b73ae4SMarcus Overhagen 	if (input.destination.port != output.destination.port) {
101865b73ae4SMarcus Overhagen 		printf("BMediaRoster::Disconnect: input.destination.port %ld doesn't match output.destination.port %ld\n",
101965b73ae4SMarcus Overhagen 			input.destination.port, output.destination.port);
102065b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
102165b73ae4SMarcus Overhagen 	}
102265b73ae4SMarcus Overhagen 	if (input.destination.id != output.destination.id) {
102365b73ae4SMarcus Overhagen 		printf("BMediaRoster::Disconnect: input.destination.id %ld doesn't match output.destination.id %ld\n",
102465b73ae4SMarcus Overhagen 			input.destination.id, output.destination.id);
102565b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
102665b73ae4SMarcus Overhagen 	}
102765b73ae4SMarcus Overhagen 	return Disconnect(output.node.node, output.source, input.node.node, input.destination);
102865b73ae4SMarcus Overhagen }
102965b73ae4SMarcus Overhagen 
103052a38012Sejakowatz 
103152a38012Sejakowatz status_t
103252a38012Sejakowatz BMediaRoster::StartNode(const media_node & node,
103352a38012Sejakowatz 						bigtime_t at_performance_time)
103452a38012Sejakowatz {
103552a38012Sejakowatz 	CALLED();
10369e9417d2Sbeveloper 	if (node.node <= 0)
103752a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
103852a38012Sejakowatz 
103960f15390Sbeveloper 	TRACE("BMediaRoster::StartNode, node %ld, at perf %Ld\n", node.node, at_performance_time);
10400e21b167Sbeveloper 
10416396865dSbeveloper 	node_start_command command;
10426396865dSbeveloper 	command.performance_time = at_performance_time;
104352a38012Sejakowatz 
10446396865dSbeveloper 	return SendToPort(node.port, NODE_START, &command, sizeof(command));
104552a38012Sejakowatz }
104652a38012Sejakowatz 
104752a38012Sejakowatz 
104852a38012Sejakowatz status_t
104952a38012Sejakowatz BMediaRoster::StopNode(const media_node & node,
105052a38012Sejakowatz 					   bigtime_t at_performance_time,
105152a38012Sejakowatz 					   bool immediate)
105252a38012Sejakowatz {
105352a38012Sejakowatz 	CALLED();
105440f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
105552a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
105652a38012Sejakowatz 
105760f15390Sbeveloper 	TRACE("BMediaRoster::StopNode, node %ld, at perf %Ld %s\n", node.node, at_performance_time, immediate ? "NOW" : "");
10580e21b167Sbeveloper 
10596396865dSbeveloper 	node_stop_command command;
10606396865dSbeveloper 	command.performance_time = at_performance_time;
10616396865dSbeveloper 	command.immediate = immediate;
106252a38012Sejakowatz 
10636396865dSbeveloper 	return SendToPort(node.port, NODE_STOP, &command, sizeof(command));
106452a38012Sejakowatz }
106552a38012Sejakowatz 
106652a38012Sejakowatz 
106752a38012Sejakowatz status_t
106852a38012Sejakowatz BMediaRoster::SeekNode(const media_node & node,
106952a38012Sejakowatz 					   bigtime_t to_media_time,
107052a38012Sejakowatz 					   bigtime_t at_performance_time)
107152a38012Sejakowatz {
107252a38012Sejakowatz 	CALLED();
107340f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
107452a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
107552a38012Sejakowatz 
107660f15390Sbeveloper 	TRACE("BMediaRoster::SeekNode, node %ld, at perf %Ld, to perf %Ld\n", node.node, at_performance_time, to_media_time);
10770e21b167Sbeveloper 
10786396865dSbeveloper 	node_seek_command command;
10796396865dSbeveloper 	command.media_time = to_media_time;
10806396865dSbeveloper 	command.performance_time = at_performance_time;
108152a38012Sejakowatz 
10826396865dSbeveloper 	return SendToPort(node.port, NODE_SEEK, &command, sizeof(command));
108352a38012Sejakowatz }
108452a38012Sejakowatz 
108552a38012Sejakowatz 
108652a38012Sejakowatz status_t
108752a38012Sejakowatz BMediaRoster::StartTimeSource(const media_node & node,
108852a38012Sejakowatz 							  bigtime_t at_real_time)
108952a38012Sejakowatz {
109052a38012Sejakowatz 	CALLED();
109160f15390Sbeveloper 	if (IS_SYSTEM_TIMESOURCE(node)) {
109260f15390Sbeveloper 		// XXX debug this
10935ac4fbd7Sbeveloper 		//ERROR("BMediaRoster::StartTimeSource node %ld is system timesource\n", node.node);
109460f15390Sbeveloper 		return B_OK;
109560f15390Sbeveloper 	}
109692e575c1Sbeveloper //	if (IS_SHADOW_TIMESOURCE(node)) {
109792e575c1Sbeveloper //		// XXX debug this
109892e575c1Sbeveloper //		ERROR("BMediaRoster::StartTimeSource node %ld is shadow timesource\n", node.node);
109992e575c1Sbeveloper //		return B_OK;
110092e575c1Sbeveloper //	}
110140f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
11025ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartTimeSource node %ld invalid\n", node.node);
110352a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
11040e21b167Sbeveloper 	}
11050e21b167Sbeveloper 	if ((node.kind & B_TIME_SOURCE) == 0) {
11065ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartTimeSource node %ld is no timesource\n", node.node);
110752a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
11080e21b167Sbeveloper 	}
11090e21b167Sbeveloper 
111060f15390Sbeveloper 	TRACE("BMediaRoster::StartTimeSource, node %ld, at real %Ld\n", node.node, at_real_time);
111152a38012Sejakowatz 
111252a38012Sejakowatz 	BTimeSource::time_source_op_info msg;
111352a38012Sejakowatz 	msg.op = BTimeSource::B_TIMESOURCE_START;
111452a38012Sejakowatz 	msg.real_time = at_real_time;
111552a38012Sejakowatz 
111652a38012Sejakowatz 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
111752a38012Sejakowatz }
111852a38012Sejakowatz 
111952a38012Sejakowatz 
112052a38012Sejakowatz status_t
112152a38012Sejakowatz BMediaRoster::StopTimeSource(const media_node & node,
112252a38012Sejakowatz 							 bigtime_t at_real_time,
112352a38012Sejakowatz 							 bool immediate)
112452a38012Sejakowatz {
112552a38012Sejakowatz 	CALLED();
112660f15390Sbeveloper 	if (IS_SYSTEM_TIMESOURCE(node)) {
112760f15390Sbeveloper 		// XXX debug this
11285ac4fbd7Sbeveloper 		//ERROR("BMediaRoster::StopTimeSource node %ld is system timesource\n", node.node);
112960f15390Sbeveloper 		return B_OK;
113060f15390Sbeveloper 	}
113192e575c1Sbeveloper //	if (IS_SHADOW_TIMESOURCE(node)) {
113292e575c1Sbeveloper //		// XXX debug this
113392e575c1Sbeveloper //		ERROR("BMediaRoster::StopTimeSource node %ld is shadow timesource\n", node.node);
113492e575c1Sbeveloper //		return B_OK;
113592e575c1Sbeveloper //	}
113640f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
11375ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopTimeSource node %ld invalid\n", node.node);
113852a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
11390e21b167Sbeveloper 	}
11400e21b167Sbeveloper 	if ((node.kind & B_TIME_SOURCE) == 0) {
11415ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopTimeSource node %ld is no timesource\n", node.node);
114252a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
11430e21b167Sbeveloper 	}
11440e21b167Sbeveloper 
114560f15390Sbeveloper 	TRACE("BMediaRoster::StopTimeSource, node %ld, at real %Ld %s\n", node.node, at_real_time, immediate ? "NOW" : "");
114652a38012Sejakowatz 
114752a38012Sejakowatz 	BTimeSource::time_source_op_info msg;
114852a38012Sejakowatz 	msg.op = immediate ? BTimeSource::B_TIMESOURCE_STOP_IMMEDIATELY : BTimeSource::B_TIMESOURCE_STOP;
114952a38012Sejakowatz 	msg.real_time = at_real_time;
115052a38012Sejakowatz 
115152a38012Sejakowatz 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
115252a38012Sejakowatz }
115352a38012Sejakowatz 
115452a38012Sejakowatz 
115552a38012Sejakowatz status_t
115652a38012Sejakowatz BMediaRoster::SeekTimeSource(const media_node & node,
115752a38012Sejakowatz 							 bigtime_t to_performance_time,
115852a38012Sejakowatz 							 bigtime_t at_real_time)
115952a38012Sejakowatz {
116052a38012Sejakowatz 	CALLED();
116160f15390Sbeveloper 	if (IS_SYSTEM_TIMESOURCE(node)) {
116260f15390Sbeveloper 		// XXX debug this
11635ac4fbd7Sbeveloper 		// ERROR("BMediaRoster::SeekTimeSource node %ld is system timesource\n", node.node);
116460f15390Sbeveloper 		// you can't seek the system time source, but
116560f15390Sbeveloper 		// returning B_ERROR would break StampTV
116660f15390Sbeveloper 		return B_OK;
116760f15390Sbeveloper 	}
116892e575c1Sbeveloper //	if (IS_SHADOW_TIMESOURCE(node)) {
116992e575c1Sbeveloper //		// XXX debug this
117092e575c1Sbeveloper //		ERROR("BMediaRoster::SeekTimeSource node %ld is shadow timesource\n", node.node);
117192e575c1Sbeveloper //		return B_OK;
117292e575c1Sbeveloper //	}
117340f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
11745ac4fbd7Sbeveloper 		ERROR("BMediaRoster::SeekTimeSource node %ld invalid\n", node.node);
117552a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
11760e21b167Sbeveloper 	}
11770e21b167Sbeveloper 	if ((node.kind & B_TIME_SOURCE) == 0) {
11785ac4fbd7Sbeveloper 		ERROR("BMediaRoster::SeekTimeSource node %ld is no timesource\n", node.node);
117952a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
11800e21b167Sbeveloper 	}
11810e21b167Sbeveloper 
118260f15390Sbeveloper 	TRACE("BMediaRoster::SeekTimeSource, node %ld, at real %Ld, to perf %Ld\n", node.node, at_real_time, to_performance_time);
118352a38012Sejakowatz 
118452a38012Sejakowatz 	BTimeSource::time_source_op_info msg;
118552a38012Sejakowatz 	msg.op = BTimeSource::B_TIMESOURCE_SEEK;
118652a38012Sejakowatz 	msg.real_time = at_real_time;
118752a38012Sejakowatz 	msg.performance_time = to_performance_time;
118852a38012Sejakowatz 
118952a38012Sejakowatz 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
119052a38012Sejakowatz }
119152a38012Sejakowatz 
119252a38012Sejakowatz 
119352a38012Sejakowatz status_t
119452a38012Sejakowatz BMediaRoster::SyncToNode(const media_node & node,
119552a38012Sejakowatz 						 bigtime_t at_time,
119652a38012Sejakowatz 						 bigtime_t timeout)
119752a38012Sejakowatz {
119852a38012Sejakowatz 	UNIMPLEMENTED();
119960f15390Sbeveloper 	return B_OK;
120052a38012Sejakowatz }
120152a38012Sejakowatz 
120252a38012Sejakowatz 
120352a38012Sejakowatz status_t
120452a38012Sejakowatz BMediaRoster::SetRunModeNode(const media_node & node,
120552a38012Sejakowatz 							 BMediaNode::run_mode mode)
120652a38012Sejakowatz {
120752a38012Sejakowatz 	CALLED();
120840f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
120952a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
121052a38012Sejakowatz 
1211dfb2ad61Sbeveloper 	node_set_run_mode_command msg;
121252a38012Sejakowatz 	msg.mode = mode;
121352a38012Sejakowatz 
121452a38012Sejakowatz 	return write_port(node.port, NODE_SET_RUN_MODE, &msg, sizeof(msg));
121552a38012Sejakowatz }
121652a38012Sejakowatz 
121752a38012Sejakowatz 
121852a38012Sejakowatz status_t
121952a38012Sejakowatz BMediaRoster::PrerollNode(const media_node & node)
122052a38012Sejakowatz {
122152a38012Sejakowatz 	CALLED();
122240f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
122352a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
122452a38012Sejakowatz 
122552a38012Sejakowatz 	char dummy;
122652a38012Sejakowatz 	return write_port(node.port, NODE_PREROLL, &dummy, sizeof(dummy));
122752a38012Sejakowatz }
122852a38012Sejakowatz 
122952a38012Sejakowatz 
123052a38012Sejakowatz status_t
123152a38012Sejakowatz BMediaRoster::RollNode(const media_node & node,
123252a38012Sejakowatz 					   bigtime_t startPerformance,
123352a38012Sejakowatz 					   bigtime_t stopPerformance,
123452a38012Sejakowatz 					   bigtime_t atMediaTime)
123552a38012Sejakowatz {
123652a38012Sejakowatz 	UNIMPLEMENTED();
123752a38012Sejakowatz 	return B_ERROR;
123852a38012Sejakowatz }
123952a38012Sejakowatz 
124052a38012Sejakowatz 
124152a38012Sejakowatz status_t
124252a38012Sejakowatz BMediaRoster::SetProducerRunModeDelay(const media_node & node,
124352a38012Sejakowatz 									  bigtime_t delay,
124452a38012Sejakowatz 									  BMediaNode::run_mode mode)
124552a38012Sejakowatz {
124660f15390Sbeveloper 	CALLED();
124760f15390Sbeveloper 	if (IS_INVALID_NODE(node))
124860f15390Sbeveloper 		return B_MEDIA_BAD_NODE;
124960f15390Sbeveloper 	if ((node.kind & B_BUFFER_PRODUCER) == 0)
125060f15390Sbeveloper 		return B_MEDIA_BAD_NODE;
125160f15390Sbeveloper 
125260f15390Sbeveloper 	producer_set_run_mode_delay_command command;
125360f15390Sbeveloper 	command.mode = mode;
125460f15390Sbeveloper 	command.delay = delay;
125560f15390Sbeveloper 
125660f15390Sbeveloper 	return SendToPort(node.port, PRODUCER_SET_RUN_MODE_DELAY, &command, sizeof(command));
125752a38012Sejakowatz }
125852a38012Sejakowatz 
125952a38012Sejakowatz 
126052a38012Sejakowatz status_t
126152a38012Sejakowatz BMediaRoster::SetProducerRate(const media_node & producer,
126252a38012Sejakowatz 							  int32 numer,
126352a38012Sejakowatz 							  int32 denom)
126452a38012Sejakowatz {
126552a38012Sejakowatz 	CALLED();
126640f36b03Sbeveloper 	if (IS_INVALID_NODE(producer))
126752a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
126852a38012Sejakowatz 	if ((producer.kind & B_BUFFER_PRODUCER) == 0)
126952a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
127052a38012Sejakowatz 
1271dfb2ad61Sbeveloper 	producer_set_play_rate_request msg;
1272dfb2ad61Sbeveloper 	producer_set_play_rate_reply reply;
127352a38012Sejakowatz 	status_t rv;
127452a38012Sejakowatz 	int32 code;
127552a38012Sejakowatz 
127652a38012Sejakowatz 	msg.numer = numer;
127752a38012Sejakowatz 	msg.denom = denom;
127852a38012Sejakowatz 	msg.reply_port = _PortPool->GetPort();
127952a38012Sejakowatz 	rv = write_port(producer.node, PRODUCER_SET_PLAY_RATE, &msg, sizeof(msg));
128052a38012Sejakowatz 	if (rv != B_OK) {
128152a38012Sejakowatz 		_PortPool->PutPort(msg.reply_port);
128252a38012Sejakowatz 		return rv;
128352a38012Sejakowatz 	}
128452a38012Sejakowatz 	rv = read_port(msg.reply_port, &code, &reply, sizeof(reply));
128552a38012Sejakowatz 	_PortPool->PutPort(msg.reply_port);
128652a38012Sejakowatz 	return (rv < B_OK) ? rv : reply.result;
128752a38012Sejakowatz }
128852a38012Sejakowatz 
128952a38012Sejakowatz 
129052a38012Sejakowatz /* Nodes will have available inputs/outputs as long as they are capable */
129152a38012Sejakowatz /* of accepting more connections. The node may create an additional */
129252a38012Sejakowatz /* output or input as the currently available is taken into usage. */
129352a38012Sejakowatz status_t
129452a38012Sejakowatz BMediaRoster::GetLiveNodeInfo(const media_node & node,
129552a38012Sejakowatz 							  live_node_info * out_live_info)
129652a38012Sejakowatz {
12979e9417d2Sbeveloper 	CALLED();
12989e9417d2Sbeveloper 	if (out_live_info == NULL)
12999e9417d2Sbeveloper 		return B_BAD_VALUE;
130040f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
13019e9417d2Sbeveloper 		return B_MEDIA_BAD_NODE;
13029e9417d2Sbeveloper 
13039e9417d2Sbeveloper 	server_get_live_node_info_request request;
13049e9417d2Sbeveloper 	server_get_live_node_info_reply reply;
13059e9417d2Sbeveloper 	status_t rv;
13069e9417d2Sbeveloper 
13079e9417d2Sbeveloper 	request.node = node;
13089e9417d2Sbeveloper 
13091299bfb2Sbeveloper 	rv = QueryServer(SERVER_GET_LIVE_NODE_INFO, &request, sizeof(request), &reply, sizeof(reply));
13109e9417d2Sbeveloper 	if (rv != B_OK)
13119e9417d2Sbeveloper 		return rv;
13129e9417d2Sbeveloper 
13139e9417d2Sbeveloper 	*out_live_info = reply.live_info;
13149e9417d2Sbeveloper 	return B_OK;
131552a38012Sejakowatz }
131652a38012Sejakowatz 
131752a38012Sejakowatz 
131852a38012Sejakowatz status_t
131952a38012Sejakowatz BMediaRoster::GetLiveNodes(live_node_info * out_live_nodes,
132052a38012Sejakowatz 						   int32 * io_total_count,
132152a38012Sejakowatz 						   const media_format * has_input,
132252a38012Sejakowatz 						   const media_format * has_output,
132352a38012Sejakowatz 						   const char * name,
132452a38012Sejakowatz 						   uint64 node_kinds)
132552a38012Sejakowatz {
13269e9417d2Sbeveloper 	CALLED();
13279e9417d2Sbeveloper 	if (out_live_nodes == NULL || io_total_count == NULL)
13289e9417d2Sbeveloper 		return B_BAD_VALUE;
13299e9417d2Sbeveloper 	if (*io_total_count <= 0)
13309e9417d2Sbeveloper 		return B_BAD_VALUE;
13319e9417d2Sbeveloper 
13329e9417d2Sbeveloper 	// XXX we also support the wildcard search as GetDormantNodes does. This needs to be documented
13339e9417d2Sbeveloper 
13349e9417d2Sbeveloper 	server_get_live_nodes_request request;
13359e9417d2Sbeveloper 	server_get_live_nodes_reply reply;
13369e9417d2Sbeveloper 	status_t rv;
13379e9417d2Sbeveloper 
13389e9417d2Sbeveloper 	request.maxcount = *io_total_count;
13399e9417d2Sbeveloper 	request.has_input = (bool) has_input;
13409e9417d2Sbeveloper 	if (has_input)
13419e9417d2Sbeveloper 		request.inputformat = *has_input; // XXX we should not make a flat copy of media_format
13429e9417d2Sbeveloper 	request.has_output = (bool) has_output;
13439e9417d2Sbeveloper 	if (has_output)
13449e9417d2Sbeveloper 		request.outputformat = *has_output; // XXX we should not make a flat copy of media_format
13459e9417d2Sbeveloper 	request.has_name = (bool) name;
13469e9417d2Sbeveloper 	if (name) {
13479e9417d2Sbeveloper 		int len = strlen(name);
13489e9417d2Sbeveloper 		len = min_c(len, (int)sizeof(request.name) - 1);
13499e9417d2Sbeveloper 		memcpy(request.name, name, len);
13509e9417d2Sbeveloper 		request.name[len] = 0;
13519e9417d2Sbeveloper 	}
13529e9417d2Sbeveloper 	request.require_kinds = node_kinds;
13539e9417d2Sbeveloper 
13549e9417d2Sbeveloper 	rv = QueryServer(SERVER_GET_LIVE_NODES, &request, sizeof(request), &reply, sizeof(reply));
13559e9417d2Sbeveloper 	if (rv != B_OK) {
13565ac4fbd7Sbeveloper 		ERROR("BMediaRoster::GetLiveNodes failed querying server\n");
13571299bfb2Sbeveloper 		*io_total_count = 0;
13589e9417d2Sbeveloper 		return rv;
13599e9417d2Sbeveloper 	}
13609e9417d2Sbeveloper 
13619e9417d2Sbeveloper 	if (reply.count > MAX_LIVE_INFO) {
13629e9417d2Sbeveloper 		live_node_info *live_info;
13639e9417d2Sbeveloper 		area_id clone;
13649e9417d2Sbeveloper 
13659e9417d2Sbeveloper 		clone = clone_area("live_node_info clone", reinterpret_cast<void **>(&live_info), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, reply.area);
13669e9417d2Sbeveloper 		if (clone < B_OK) {
13675ac4fbd7Sbeveloper 			ERROR("BMediaRoster::GetLiveNodes failed to clone area, %#lx\n", clone);
13689e9417d2Sbeveloper 			delete_area(reply.area);
13691299bfb2Sbeveloper 			*io_total_count = 0;
137052a38012Sejakowatz 			return B_ERROR;
137152a38012Sejakowatz 		}
137252a38012Sejakowatz 
13739e9417d2Sbeveloper 		for (int32 i = 0; i < reply.count; i++) {
13749e9417d2Sbeveloper 			out_live_nodes[i] = live_info[i];
13759e9417d2Sbeveloper 		}
13769e9417d2Sbeveloper 
13779e9417d2Sbeveloper 		delete_area(clone);
13789e9417d2Sbeveloper 		delete_area(reply.area);
13799e9417d2Sbeveloper 	} else {
13809e9417d2Sbeveloper 		for (int32 i = 0; i < reply.count; i++) {
13819e9417d2Sbeveloper 			out_live_nodes[i] = reply.live_info[i];
13829e9417d2Sbeveloper 		}
13839e9417d2Sbeveloper 	}
13849e9417d2Sbeveloper 	*io_total_count = reply.count;
13859e9417d2Sbeveloper 
13869e9417d2Sbeveloper 	return B_OK;
13879e9417d2Sbeveloper }
13889e9417d2Sbeveloper 
138952a38012Sejakowatz 
139052a38012Sejakowatz status_t
139152a38012Sejakowatz BMediaRoster::GetFreeInputsFor(const media_node & node,
139252a38012Sejakowatz 							   media_input * out_free_inputs,
139352a38012Sejakowatz 							   int32 buf_num_inputs,
139452a38012Sejakowatz 							   int32 * out_total_count,
139552a38012Sejakowatz 							   media_type filter_type)
139652a38012Sejakowatz {
13973620737cSbeveloper 	CALLED();
13985ac4fbd7Sbeveloper 	if (IS_INVALID_NODE(node)) {
13995ac4fbd7Sbeveloper 		ERROR("BMediaRoster::GetFreeInputsFor: node %ld, port %ld invalid\n", node.node, node.port);
14003620737cSbeveloper 		return B_MEDIA_BAD_NODE;
14015ac4fbd7Sbeveloper 	}
14025ac4fbd7Sbeveloper 	if ((node.kind & B_BUFFER_CONSUMER) == 0) {
14035ac4fbd7Sbeveloper 		ERROR("BMediaRoster::GetFreeInputsFor: node %ld, port %ld is not a consumer\n", node.node, node.port);
14045ac4fbd7Sbeveloper 		return B_MEDIA_BAD_NODE;
14055ac4fbd7Sbeveloper 	}
14063620737cSbeveloper 	if (out_free_inputs == NULL || out_total_count == NULL)
14073620737cSbeveloper 		return B_BAD_VALUE;
14083620737cSbeveloper 
140976669a29Sbeveloper 	List<media_input> list;
14103620737cSbeveloper 	media_input *input;
14113620737cSbeveloper 	status_t rv;
14123620737cSbeveloper 
14131299bfb2Sbeveloper 	*out_total_count = 0;
14141299bfb2Sbeveloper 
14158b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllInputs(node, &list);
14163620737cSbeveloper 	if (B_OK != rv)
14173620737cSbeveloper 		return rv;
14183620737cSbeveloper 
14195ac4fbd7Sbeveloper 	PRINT(4, "BMediaRoster::GetFreeInputsFor node %ld, max %ld, filter-type %ld\n", node.node, buf_num_inputs, filter_type);
14205ac4fbd7Sbeveloper 
142176669a29Sbeveloper 	int32 i;
1422b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&input);) {
14233620737cSbeveloper 		if (filter_type != B_MEDIA_UNKNOWN_TYPE && filter_type != input->format.type)
14243620737cSbeveloper 			continue; // media_type used, but doesn't match
14253620737cSbeveloper 		if (input->source != media_source::null)
14263620737cSbeveloper 			continue; // consumer source already connected
14273620737cSbeveloper 		out_free_inputs[i] = *input;
14283620737cSbeveloper 		*out_total_count += 1;
14293620737cSbeveloper 		buf_num_inputs -= 1;
14305ac4fbd7Sbeveloper 		#if DEBUG >= 3
14315ac4fbd7Sbeveloper 			PRINT_OUTPUT("  input", out_free_inputs[i]);
14325ac4fbd7Sbeveloper 		#endif
14333620737cSbeveloper 		if (buf_num_inputs == 0)
14343620737cSbeveloper 			break;
1435b65a0ac5SJérôme Duval 		i++;
14363620737cSbeveloper 	}
14373620737cSbeveloper 
14388b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishInputs(node, &list);
14393620737cSbeveloper 	return B_OK;
144052a38012Sejakowatz }
144152a38012Sejakowatz 
144252a38012Sejakowatz 
144352a38012Sejakowatz status_t
144452a38012Sejakowatz BMediaRoster::GetConnectedInputsFor(const media_node & node,
144552a38012Sejakowatz 									media_input * out_active_inputs,
144652a38012Sejakowatz 									int32 buf_num_inputs,
144752a38012Sejakowatz 									int32 * out_total_count)
144852a38012Sejakowatz {
14493620737cSbeveloper 	CALLED();
145040f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_CONSUMER) == 0)
14513620737cSbeveloper 		return B_MEDIA_BAD_NODE;
14523620737cSbeveloper 	if (out_active_inputs == NULL || out_total_count == NULL)
14533620737cSbeveloper 		return B_BAD_VALUE;
14543620737cSbeveloper 
145576669a29Sbeveloper 	List<media_input> list;
14563620737cSbeveloper 	media_input *input;
14573620737cSbeveloper 	status_t rv;
14583620737cSbeveloper 
14591299bfb2Sbeveloper 	*out_total_count = 0;
14601299bfb2Sbeveloper 
14618b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllInputs(node, &list);
14623620737cSbeveloper 	if (B_OK != rv)
14633620737cSbeveloper 		return rv;
14643620737cSbeveloper 
14655ac4fbd7Sbeveloper 	PRINT(4, "BMediaRoster::GetConnectedInputsFor node %ld, max %ld\n", node.node, buf_num_inputs);
14665ac4fbd7Sbeveloper 
146776669a29Sbeveloper 	int32 i;
1468b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&input);) {
14693620737cSbeveloper 		if (input->source == media_source::null)
14703620737cSbeveloper 			continue; // consumer source not connected
14713620737cSbeveloper 		out_active_inputs[i] = *input;
14723620737cSbeveloper 		*out_total_count += 1;
14733620737cSbeveloper 		buf_num_inputs -= 1;
14745ac4fbd7Sbeveloper 		#if DEBUG >= 3
14755ac4fbd7Sbeveloper 			PRINT_OUTPUT("  input ", out_active_inputs[i]);
14765ac4fbd7Sbeveloper 		#endif
14773620737cSbeveloper 		if (buf_num_inputs == 0)
14783620737cSbeveloper 			break;
1479b65a0ac5SJérôme Duval 		i++;
14803620737cSbeveloper 	}
14813620737cSbeveloper 
14828b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishInputs(node, &list);
14833620737cSbeveloper 	return B_OK;
148452a38012Sejakowatz }
148552a38012Sejakowatz 
148652a38012Sejakowatz 
148752a38012Sejakowatz status_t
148852a38012Sejakowatz BMediaRoster::GetAllInputsFor(const media_node & node,
148952a38012Sejakowatz 							  media_input * out_inputs,
149052a38012Sejakowatz 							  int32 buf_num_inputs,
149152a38012Sejakowatz 							  int32 * out_total_count)
149252a38012Sejakowatz {
149352a38012Sejakowatz 	CALLED();
149440f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_CONSUMER) == 0)
149552a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
149652a38012Sejakowatz 	if (out_inputs == NULL || out_total_count == NULL)
149752a38012Sejakowatz 		return B_BAD_VALUE;
149852a38012Sejakowatz 
149976669a29Sbeveloper 	List<media_input> list;
15003620737cSbeveloper 	media_input *input;
150152a38012Sejakowatz 	status_t rv;
150252a38012Sejakowatz 
15031299bfb2Sbeveloper 	*out_total_count = 0;
15041299bfb2Sbeveloper 
15058b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllInputs(node, &list);
15063620737cSbeveloper 	if (B_OK != rv)
15073620737cSbeveloper 		return rv;
15083620737cSbeveloper 
15095ac4fbd7Sbeveloper 	PRINT(4, "BMediaRoster::GetAllInputsFor node %ld, max %ld\n", node.node, buf_num_inputs);
15105ac4fbd7Sbeveloper 
151176669a29Sbeveloper 	int32 i;
151276669a29Sbeveloper 	for (i = 0, list.Rewind(); list.GetNext(&input); i++) {
15133620737cSbeveloper 		out_inputs[i] = *input;
151452a38012Sejakowatz 		*out_total_count += 1;
15153620737cSbeveloper 		buf_num_inputs -= 1;
15165ac4fbd7Sbeveloper 		#if DEBUG >= 3
15175ac4fbd7Sbeveloper 			PRINT_OUTPUT("  input ", out_inputs[i]);
15185ac4fbd7Sbeveloper 		#endif
15193620737cSbeveloper 		if (buf_num_inputs == 0)
15203620737cSbeveloper 			break;
152152a38012Sejakowatz 	}
152252a38012Sejakowatz 
15238b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishInputs(node, &list);
15243620737cSbeveloper 	return B_OK;
152552a38012Sejakowatz }
152652a38012Sejakowatz 
152752a38012Sejakowatz 
152852a38012Sejakowatz status_t
152952a38012Sejakowatz BMediaRoster::GetFreeOutputsFor(const media_node & node,
153052a38012Sejakowatz 								media_output * out_free_outputs,
153152a38012Sejakowatz 								int32 buf_num_outputs,
153252a38012Sejakowatz 								int32 * out_total_count,
153352a38012Sejakowatz 								media_type filter_type)
153452a38012Sejakowatz {
15353620737cSbeveloper 	CALLED();
153640f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0)
15373620737cSbeveloper 		return B_MEDIA_BAD_NODE;
15383620737cSbeveloper 	if (out_free_outputs == NULL || out_total_count == NULL)
15393620737cSbeveloper 		return B_BAD_VALUE;
15403620737cSbeveloper 
154176669a29Sbeveloper 	List<media_output> list;
15423620737cSbeveloper 	media_output *output;
15433620737cSbeveloper 	status_t rv;
15443620737cSbeveloper 
15451299bfb2Sbeveloper 	*out_total_count = 0;
15461299bfb2Sbeveloper 
15478b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllOutputs(node, &list);
15483620737cSbeveloper 	if (B_OK != rv)
15493620737cSbeveloper 		return rv;
15503620737cSbeveloper 
15515ac4fbd7Sbeveloper 	PRINT(4, "BMediaRoster::GetFreeOutputsFor node %ld, max %ld, filter-type %ld\n", node.node, buf_num_outputs, filter_type);
15525ac4fbd7Sbeveloper 
155376669a29Sbeveloper 	int32 i;
1554b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&output);) {
15553620737cSbeveloper 		if (filter_type != B_MEDIA_UNKNOWN_TYPE && filter_type != output->format.type)
15563620737cSbeveloper 			continue; // media_type used, but doesn't match
15573620737cSbeveloper 		if (output->destination != media_destination::null)
15583620737cSbeveloper 			continue; // producer destination already connected
15593620737cSbeveloper 		out_free_outputs[i] = *output;
15603620737cSbeveloper 		*out_total_count += 1;
15613620737cSbeveloper 		buf_num_outputs -= 1;
15625ac4fbd7Sbeveloper 		#if DEBUG >= 3
15635ac4fbd7Sbeveloper 			PRINT_OUTPUT("  output ", out_free_outputs[i]);
15645ac4fbd7Sbeveloper 		#endif
15653620737cSbeveloper 		if (buf_num_outputs == 0)
15663620737cSbeveloper 			break;
1567b65a0ac5SJérôme Duval 		i++;
15683620737cSbeveloper 	}
15693620737cSbeveloper 
15708b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishOutputs(node, &list);
15713620737cSbeveloper 	return B_OK;
157252a38012Sejakowatz }
157352a38012Sejakowatz 
157452a38012Sejakowatz 
157552a38012Sejakowatz status_t
157652a38012Sejakowatz BMediaRoster::GetConnectedOutputsFor(const media_node & node,
157752a38012Sejakowatz 									 media_output * out_active_outputs,
157852a38012Sejakowatz 									 int32 buf_num_outputs,
157952a38012Sejakowatz 									 int32 * out_total_count)
158052a38012Sejakowatz {
15813620737cSbeveloper 	CALLED();
158240f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0)
15833620737cSbeveloper 		return B_MEDIA_BAD_NODE;
15843620737cSbeveloper 	if (out_active_outputs == NULL || out_total_count == NULL)
15853620737cSbeveloper 		return B_BAD_VALUE;
15863620737cSbeveloper 
158776669a29Sbeveloper 	List<media_output> list;
15883620737cSbeveloper 	media_output *output;
15893620737cSbeveloper 	status_t rv;
15903620737cSbeveloper 
15911299bfb2Sbeveloper 	*out_total_count = 0;
15921299bfb2Sbeveloper 
15938b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllOutputs(node, &list);
15943620737cSbeveloper 	if (B_OK != rv)
15953620737cSbeveloper 		return rv;
15963620737cSbeveloper 
15975ac4fbd7Sbeveloper 	PRINT(4, "BMediaRoster::GetConnectedOutputsFor node %ld, max %ld\n", node.node, buf_num_outputs);
15985ac4fbd7Sbeveloper 
159976669a29Sbeveloper 	int32 i;
1600b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&output);) {
16013620737cSbeveloper 		if (output->destination == media_destination::null)
16023620737cSbeveloper 			continue; // producer destination not connected
16033620737cSbeveloper 		out_active_outputs[i] = *output;
16043620737cSbeveloper 		*out_total_count += 1;
16053620737cSbeveloper 		buf_num_outputs -= 1;
16065ac4fbd7Sbeveloper 		#if DEBUG >= 3
16075ac4fbd7Sbeveloper 			PRINT_OUTPUT("  output ", out_active_outputs[i]);
16085ac4fbd7Sbeveloper 		#endif
16093620737cSbeveloper 		if (buf_num_outputs == 0)
16103620737cSbeveloper 			break;
1611b65a0ac5SJérôme Duval 		i++;
16123620737cSbeveloper 	}
16133620737cSbeveloper 
16148b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishOutputs(node, &list);
16153620737cSbeveloper 	return B_OK;
161652a38012Sejakowatz }
161752a38012Sejakowatz 
161852a38012Sejakowatz 
161952a38012Sejakowatz status_t
162052a38012Sejakowatz BMediaRoster::GetAllOutputsFor(const media_node & node,
162152a38012Sejakowatz 							   media_output * out_outputs,
162252a38012Sejakowatz 							   int32 buf_num_outputs,
162352a38012Sejakowatz 							   int32 * out_total_count)
162452a38012Sejakowatz {
162552a38012Sejakowatz 	CALLED();
162640f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0)
162752a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
162852a38012Sejakowatz 	if (out_outputs == NULL || out_total_count == NULL)
162952a38012Sejakowatz 		return B_BAD_VALUE;
163052a38012Sejakowatz 
163176669a29Sbeveloper 	List<media_output> list;
16323620737cSbeveloper 	media_output *output;
163352a38012Sejakowatz 	status_t rv;
163452a38012Sejakowatz 
16351299bfb2Sbeveloper 	*out_total_count = 0;
16361299bfb2Sbeveloper 
16378b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllOutputs(node, &list);
16383620737cSbeveloper 	if (B_OK != rv)
16393620737cSbeveloper 		return rv;
16403620737cSbeveloper 
16415ac4fbd7Sbeveloper 	PRINT(4, "BMediaRoster::GetAllOutputsFor node %ld, max %ld\n", node.node, buf_num_outputs);
16425ac4fbd7Sbeveloper 
164376669a29Sbeveloper 	int32 i;
164476669a29Sbeveloper 	for (i = 0, list.Rewind(); list.GetNext(&output); i++) {
16453620737cSbeveloper 		out_outputs[i] = *output;
164652a38012Sejakowatz 		*out_total_count += 1;
16473620737cSbeveloper 		buf_num_outputs -= 1;
16485ac4fbd7Sbeveloper 		#if DEBUG >= 3
16495ac4fbd7Sbeveloper 			PRINT_OUTPUT("  output ", out_outputs[i]);
16505ac4fbd7Sbeveloper 		#endif
16513620737cSbeveloper 		if (buf_num_outputs == 0)
16523620737cSbeveloper 			break;
165352a38012Sejakowatz 	}
165452a38012Sejakowatz 
16558b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishOutputs(node, &list);
16563620737cSbeveloper 	return B_OK;
165752a38012Sejakowatz }
165852a38012Sejakowatz 
165952a38012Sejakowatz 
166052a38012Sejakowatz status_t
166152a38012Sejakowatz BMediaRoster::StartWatching(const BMessenger & where)
166252a38012Sejakowatz {
1663eae26d3dSbeveloper 	CALLED();
1664eae26d3dSbeveloper 	if (!where.IsValid()) {
16655ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: messenger invalid!\n");
1666eae26d3dSbeveloper 		return B_BAD_VALUE;
1667eae26d3dSbeveloper 	}
1668f4925104Sbeveloper 	return BPrivate::media::notifications::Register(where, media_node::null, B_MEDIA_WILDCARD);
166952a38012Sejakowatz }
167052a38012Sejakowatz 
167152a38012Sejakowatz 
167252a38012Sejakowatz status_t
167352a38012Sejakowatz BMediaRoster::StartWatching(const BMessenger & where,
167452a38012Sejakowatz 							int32 notificationType)
167552a38012Sejakowatz {
1676eae26d3dSbeveloper 	CALLED();
1677eae26d3dSbeveloper 	if (!where.IsValid()) {
16785ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: messenger invalid!\n");
1679eae26d3dSbeveloper 		return B_BAD_VALUE;
1680eae26d3dSbeveloper 	}
1681f4925104Sbeveloper 	if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) {
16825ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: notificationType invalid!\n");
1683eae26d3dSbeveloper 		return B_BAD_VALUE;
1684eae26d3dSbeveloper 	}
1685f4925104Sbeveloper 	return BPrivate::media::notifications::Register(where, media_node::null, notificationType);
168652a38012Sejakowatz }
168752a38012Sejakowatz 
168852a38012Sejakowatz 
168952a38012Sejakowatz status_t
169052a38012Sejakowatz BMediaRoster::StartWatching(const BMessenger & where,
169152a38012Sejakowatz 							const media_node & node,
169252a38012Sejakowatz 							int32 notificationType)
169352a38012Sejakowatz {
1694eae26d3dSbeveloper 	CALLED();
1695eae26d3dSbeveloper 	if (!where.IsValid()) {
16965ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: messenger invalid!\n");
1697eae26d3dSbeveloper 		return B_BAD_VALUE;
1698eae26d3dSbeveloper 	}
169940f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
17005ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: node invalid!\n");
1701eae26d3dSbeveloper 		return B_MEDIA_BAD_NODE;
1702eae26d3dSbeveloper 	}
1703f4925104Sbeveloper 	if (false == BPrivate::media::notifications::IsValidNotificationRequest(true, notificationType)) {
17045ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: notificationType invalid!\n");
1705eae26d3dSbeveloper 		return B_BAD_VALUE;
1706eae26d3dSbeveloper 	}
1707f4925104Sbeveloper 	return BPrivate::media::notifications::Register(where, node, notificationType);
170852a38012Sejakowatz }
170952a38012Sejakowatz 
171052a38012Sejakowatz 
171152a38012Sejakowatz status_t
171252a38012Sejakowatz BMediaRoster::StopWatching(const BMessenger & where)
171352a38012Sejakowatz {
1714eae26d3dSbeveloper 	CALLED();
1715eae26d3dSbeveloper 	// messenger may already be invalid, so we don't check this
1716f4925104Sbeveloper 	return BPrivate::media::notifications::Unregister(where, media_node::null, B_MEDIA_WILDCARD);
171752a38012Sejakowatz }
171852a38012Sejakowatz 
171952a38012Sejakowatz 
172052a38012Sejakowatz status_t
172152a38012Sejakowatz BMediaRoster::StopWatching(const BMessenger & where,
172252a38012Sejakowatz 						   int32 notificationType)
172352a38012Sejakowatz {
1724eae26d3dSbeveloper 	CALLED();
1725eae26d3dSbeveloper 	// messenger may already be invalid, so we don't check this
1726f4925104Sbeveloper 	if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) {
17275ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopWatching: notificationType invalid!\n");
1728eae26d3dSbeveloper 		return B_BAD_VALUE;
1729eae26d3dSbeveloper 	}
1730f4925104Sbeveloper 	return BPrivate::media::notifications::Unregister(where, media_node::null, notificationType);
173152a38012Sejakowatz }
173252a38012Sejakowatz 
173352a38012Sejakowatz 
173452a38012Sejakowatz status_t
173552a38012Sejakowatz BMediaRoster::StopWatching(const BMessenger & where,
173652a38012Sejakowatz 						   const media_node & node,
173752a38012Sejakowatz 						   int32 notificationType)
173852a38012Sejakowatz {
1739eae26d3dSbeveloper 	CALLED();
1740eae26d3dSbeveloper 	// messenger may already be invalid, so we don't check this
174140f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
17425ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopWatching: node invalid!\n");
1743eae26d3dSbeveloper 		return B_MEDIA_BAD_NODE;
1744eae26d3dSbeveloper 	}
1745f4925104Sbeveloper 	if (false == BPrivate::media::notifications::IsValidNotificationRequest(true, notificationType)) {
17465ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopWatching: notificationType invalid!\n");
1747eae26d3dSbeveloper 		return B_BAD_VALUE;
1748eae26d3dSbeveloper 	}
1749f4925104Sbeveloper 	return BPrivate::media::notifications::Unregister(where, node, notificationType);
175052a38012Sejakowatz }
175152a38012Sejakowatz 
175252a38012Sejakowatz 
175352a38012Sejakowatz status_t
175452a38012Sejakowatz BMediaRoster::RegisterNode(BMediaNode * node)
175552a38012Sejakowatz {
175654187cc6Sbeveloper 	CALLED();
175754187cc6Sbeveloper 	// addon-id = -1 (unused), addon-flavor-id = 0 (unused, too)
175854187cc6Sbeveloper 	return MediaRosterEx(this)->RegisterNode(node, -1, 0);
175954187cc6Sbeveloper }
176054187cc6Sbeveloper 
176154187cc6Sbeveloper 
176254187cc6Sbeveloper status_t
176354187cc6Sbeveloper BMediaRosterEx::RegisterNode(BMediaNode * node, media_addon_id addonid, int32 flavorid)
176454187cc6Sbeveloper {
176552a38012Sejakowatz 	CALLED();
176652a38012Sejakowatz 	if (node == NULL)
176752a38012Sejakowatz 		return B_BAD_VALUE;
176852a38012Sejakowatz 
176954187cc6Sbeveloper 	// some sanity check
177054187cc6Sbeveloper 	// I'm not sure if the media kit warrants to call BMediaNode::AddOn() here.
177154187cc6Sbeveloper 	// Perhaps we don't need it.
177254187cc6Sbeveloper 	{
17739e9417d2Sbeveloper 		BMediaAddOn *addon;
17749e9417d2Sbeveloper 		int32 addon_flavor_id;
17759e9417d2Sbeveloper 		media_addon_id addon_id;
17769e9417d2Sbeveloper 		addon_flavor_id = 0;
17779e9417d2Sbeveloper 		addon = node->AddOn(&addon_flavor_id);
17789e9417d2Sbeveloper 		addon_id = addon ? addon->AddonID() : -1;
177954187cc6Sbeveloper 		ASSERT(addonid == addon_id);
178054187cc6Sbeveloper 		ASSERT(flavorid == addon_flavor_id);
178154187cc6Sbeveloper 	}
178252a38012Sejakowatz 
178354187cc6Sbeveloper 	status_t rv;
17849e9417d2Sbeveloper 	server_register_node_request request;
17859e9417d2Sbeveloper 	server_register_node_reply reply;
17869e9417d2Sbeveloper 
178754187cc6Sbeveloper 	request.addon_id = addonid;
178854187cc6Sbeveloper 	request.addon_flavor_id = flavorid;
17899e9417d2Sbeveloper 	strcpy(request.name, node->Name());
17909e9417d2Sbeveloper 	request.kinds = node->Kinds();
17919e9417d2Sbeveloper 	request.port = node->ControlPort();
17929e9417d2Sbeveloper 	request.team = team;
17939e9417d2Sbeveloper 
17948b04ffc1Sbeveloper 	TRACE("BMediaRoster::RegisterNode: sending SERVER_REGISTER_NODE: port %ld, kinds 0x%Lx, team %ld, name '%s'\n", request.port, request.kinds, request.team, request.name);
17951299bfb2Sbeveloper 
17969e9417d2Sbeveloper 	rv = QueryServer(SERVER_REGISTER_NODE, &request, sizeof(request), &reply, sizeof(reply));
17979e9417d2Sbeveloper 	if (rv != B_OK) {
17985ac4fbd7Sbeveloper 		ERROR("BMediaRoster::RegisterNode: failed to register node %s (error %#lx)\n", node->Name(), rv);
17999e9417d2Sbeveloper 		return rv;
18009e9417d2Sbeveloper 	}
18019e9417d2Sbeveloper 
18024295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: QueryServer SERVER_REGISTER_NODE finished\n");
18034295907bSbeveloper 
18048b04ffc1Sbeveloper 	// we are a friend class of BMediaNode and initialize this member variable
18059e9417d2Sbeveloper 	node->fNodeID = reply.nodeid;
18069e9417d2Sbeveloper 	ASSERT(reply.nodeid == node->Node().node);
18079e9417d2Sbeveloper 	ASSERT(reply.nodeid == node->ID());
18089e9417d2Sbeveloper 
18099e9417d2Sbeveloper 	// call the callback
18109e9417d2Sbeveloper 	node->NodeRegistered();
18113620737cSbeveloper 
18124295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: NodeRegistered callback finished\n");
18134295907bSbeveloper 
18140e21b167Sbeveloper 	// if the BMediaNode also inherits from BTimeSource, we need to call BTimeSource::FinishCreate()
18150e21b167Sbeveloper 	if (node->Kinds() & B_TIME_SOURCE) {
18160e21b167Sbeveloper 		BTimeSource *ts;
18170e21b167Sbeveloper 		ts = dynamic_cast<BTimeSource *>(node);
18180e21b167Sbeveloper 		if (ts)
18190e21b167Sbeveloper 			ts->FinishCreate();
18200e21b167Sbeveloper 	}
18210e21b167Sbeveloper 
18224295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: publishing inputs/outputs\n");
18234295907bSbeveloper 
18243620737cSbeveloper 	// register existing inputs and outputs with the
18253620737cSbeveloper 	// media_server, this allows GetLiveNodes() to work
18263620737cSbeveloper 	// with created, but unconnected nodes.
18274d2d96e0Sbeveloper 	// The node control loop might not be running, or might deadlock
18284d2d96e0Sbeveloper 	// if we send a message and wait for a reply here.
18294d2d96e0Sbeveloper 	// We have a pointer to the node, and thus call the functions directly
18304295907bSbeveloper 
18313620737cSbeveloper 	if (node->Kinds() & B_BUFFER_PRODUCER) {
18324d2d96e0Sbeveloper 		BBufferProducer *bp;
18334d2d96e0Sbeveloper 		bp = dynamic_cast<BBufferProducer *>(node);
18344d2d96e0Sbeveloper 		if (bp) {
1835359ac306Sbeveloper 			List<media_output> list;
18364d2d96e0Sbeveloper 			if (B_OK == GetAllOutputs(bp, &list))
1837359ac306Sbeveloper 				PublishOutputs(node->Node(), &list);
183821871f38Sbeveloper 		}
18394d2d96e0Sbeveloper 	}
184021871f38Sbeveloper 	if (node->Kinds() & B_BUFFER_CONSUMER) {
18414d2d96e0Sbeveloper 		BBufferConsumer *bc;
18424d2d96e0Sbeveloper 		bc = dynamic_cast<BBufferConsumer *>(node);
18434d2d96e0Sbeveloper 		if (bc) {
1844359ac306Sbeveloper 			List<media_input> list;
18454d2d96e0Sbeveloper 			if (B_OK == GetAllInputs(bc, &list))
1846359ac306Sbeveloper 				PublishInputs(node->Node(), &list);
18473620737cSbeveloper 		}
18484d2d96e0Sbeveloper 	}
184921871f38Sbeveloper 
18504295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: sending NodesCreated\n");
18514295907bSbeveloper 
18521299bfb2Sbeveloper 	BPrivate::media::notifications::NodesCreated(&reply.nodeid, 1);
18534295907bSbeveloper 
18544295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: finished\n");
18554295907bSbeveloper 
1856570f7d04Sbeveloper /*
1857570f7d04Sbeveloper 	TRACE("BMediaRoster::RegisterNode: registered node name '%s', id %ld, addon %ld, flavor %ld\n", node->Name(), node->ID(), addon_id, addon_flavor_id);
1858570f7d04Sbeveloper 	TRACE("BMediaRoster::RegisterNode: node this               %p\n", node);
1859570f7d04Sbeveloper 	TRACE("BMediaRoster::RegisterNode: node fConsumerThis      %p\n", node->fConsumerThis);
1860570f7d04Sbeveloper 	TRACE("BMediaRoster::RegisterNode: node fProducerThis      %p\n", node->fProducerThis);
1861570f7d04Sbeveloper 	TRACE("BMediaRoster::RegisterNode: node fFileInterfaceThis %p\n", node->fFileInterfaceThis);
1862570f7d04Sbeveloper 	TRACE("BMediaRoster::RegisterNode: node fControllableThis  %p\n", node->fControllableThis);
1863570f7d04Sbeveloper 	TRACE("BMediaRoster::RegisterNode: node fTimeSourceThis    %p\n", node->fTimeSourceThis);
1864570f7d04Sbeveloper */
18659e9417d2Sbeveloper 	return B_OK;
186652a38012Sejakowatz }
186752a38012Sejakowatz 
186852a38012Sejakowatz 
186952a38012Sejakowatz status_t
187052a38012Sejakowatz BMediaRoster::UnregisterNode(BMediaNode * node)
187152a38012Sejakowatz {
18729e9417d2Sbeveloper 	CALLED();
18739e9417d2Sbeveloper 	if (node == NULL)
18749e9417d2Sbeveloper 		return B_BAD_VALUE;
18759e9417d2Sbeveloper 
187660f15390Sbeveloper 	TRACE("BMediaRoster::UnregisterNode %ld (%p)\n", node->ID(), node);
187760f15390Sbeveloper 
187886bce45bSbeveloper 	if (node->fKinds & NODE_KIND_NO_REFCOUNTING) {
187986bce45bSbeveloper 		printf("BMediaRoster::UnregisterNode, trying to unregister reference counting disabled timesource, node %ld, port %ld, team %ld\n", node->ID(), node->ControlPort(), team);
188086bce45bSbeveloper 		return B_OK;
188186bce45bSbeveloper 	}
18828b04ffc1Sbeveloper 	if (node->ID() == NODE_UNREGISTERED_ID) {
18835ac4fbd7Sbeveloper 		PRINT(1, "Warning: BMediaRoster::UnregisterNode: node id %ld, name '%s' already unregistered\n", node->ID(), node->Name());
18849e9417d2Sbeveloper 		return B_OK;
18859e9417d2Sbeveloper 	}
188654187cc6Sbeveloper 	if (node->fRefCount != 0) {
18875ac4fbd7Sbeveloper 		PRINT(1, "Warning: BMediaRoster::UnregisterNode: node id %ld, name '%s' has local reference count of %ld\n", node->ID(), node->Name(), node->fRefCount);
188854187cc6Sbeveloper 		// no return here, we continue and unregister!
188954187cc6Sbeveloper 	}
189054187cc6Sbeveloper 
189154187cc6Sbeveloper 	// Calling BMediaAddOn::GetConfigurationFor(BMediaNode *node, BMessage *config)
189254187cc6Sbeveloper 	// if this node was instanciated by an add-on needs to be done *somewhere*
189354187cc6Sbeveloper 	// We can't do it here because it is already to late (destructor of the node
189454187cc6Sbeveloper 	// might have been called).
18959e9417d2Sbeveloper 
18969e9417d2Sbeveloper 	server_unregister_node_request request;
18979e9417d2Sbeveloper 	server_unregister_node_reply reply;
18989e9417d2Sbeveloper 	status_t rv;
18999e9417d2Sbeveloper 
19009e9417d2Sbeveloper 	request.nodeid = node->ID();
19019e9417d2Sbeveloper 	request.team = team;
19029e9417d2Sbeveloper 
19031299bfb2Sbeveloper 	// send a notification
19041299bfb2Sbeveloper 	BPrivate::media::notifications::NodesDeleted(&request.nodeid, 1);
19051299bfb2Sbeveloper 
19069e9417d2Sbeveloper 	rv = QueryServer(SERVER_UNREGISTER_NODE, &request, sizeof(request), &reply, sizeof(reply));
19079e9417d2Sbeveloper 	if (rv != B_OK) {
19085ac4fbd7Sbeveloper 		ERROR("BMediaRoster::UnregisterNode: failed to unregister node id %ld, name '%s' (error %#lx)\n", node->ID(), node->Name(), rv);
19099e9417d2Sbeveloper 		return rv;
19109e9417d2Sbeveloper 	}
19119e9417d2Sbeveloper 
191254187cc6Sbeveloper 	if (reply.addonid != -1) {
191354187cc6Sbeveloper 		// Small problem here, we can't use DormantNodeManager::PutAddon(), as
191454187cc6Sbeveloper 		// UnregisterNode() is called by a dormant node itself (by the destructor).
191554187cc6Sbeveloper 		// The add-on that contains the node needs to remain in memory until the
191654187cc6Sbeveloper 		// destructor execution is finished.
191754187cc6Sbeveloper 		// DormantNodeManager::PutAddonDelayed() will delay unloading.
191854187cc6Sbeveloper 		_DormantNodeManager->PutAddonDelayed(reply.addonid);
1919cf4e2277Sbeveloper 
192073794717Sbeveloper 		rv = MediaRosterEx(this)->DecrementAddonFlavorInstancesCount(reply.addonid, reply.flavorid);
192154187cc6Sbeveloper 		if (rv != B_OK) {
19225ac4fbd7Sbeveloper 			ERROR("BMediaRoster::UnregisterNode: DecrementAddonFlavorInstancesCount failed\n");
192354187cc6Sbeveloper 			// this is really a problem, but we can't fail now
192454187cc6Sbeveloper 		}
19258b04ffc1Sbeveloper 	}
19269e9417d2Sbeveloper 
19271299bfb2Sbeveloper 	// we are a friend class of BMediaNode and invalidate this member variable
19288b04ffc1Sbeveloper 	node->fNodeID = NODE_UNREGISTERED_ID;
19299e9417d2Sbeveloper 
19309e9417d2Sbeveloper 	return B_OK;
193152a38012Sejakowatz }
193252a38012Sejakowatz 
193352a38012Sejakowatz 
193452a38012Sejakowatz //	thread safe for multiple calls to Roster()
193552a38012Sejakowatz /* static */ BMediaRoster *
193652a38012Sejakowatz BMediaRoster::Roster(status_t *out_error)
193752a38012Sejakowatz {
193852a38012Sejakowatz 	static BLocker locker("BMediaRoster::Roster locker");
193952a38012Sejakowatz 	locker.Lock();
19408496c38aSbeveloper 	if (out_error)
19418496c38aSbeveloper 		*out_error = B_OK;
194252a38012Sejakowatz 	if (_sDefault == NULL) {
19438496c38aSbeveloper 		status_t err;
1944dcfb6bfcSJérôme Duval 		_sDefault = new BMediaRosterEx(&err);
1945dcfb6bfcSJérôme Duval 		if (err != B_OK) {
1946dcfb6bfcSJérôme Duval 			if (_sDefault) {
1947dcfb6bfcSJérôme Duval 				_sDefault->Lock();
1948dcfb6bfcSJérôme Duval 				_sDefault->Quit();
1949dcfb6bfcSJérôme Duval 				_sDefault = NULL;
1950dcfb6bfcSJérôme Duval 			}
19518496c38aSbeveloper 			if (out_error)
19528496c38aSbeveloper 				*out_error = err;
19538496c38aSbeveloper 		}
195452a38012Sejakowatz 	}
195552a38012Sejakowatz 	locker.Unlock();
195652a38012Sejakowatz 	return _sDefault;
195752a38012Sejakowatz }
195852a38012Sejakowatz 
195952a38012Sejakowatz 
196052a38012Sejakowatz //	won't create it if there isn't one
196152a38012Sejakowatz //	not thread safe if you call Roster() at the same time
196252a38012Sejakowatz /* static */ BMediaRoster *
196352a38012Sejakowatz BMediaRoster::CurrentRoster()
196452a38012Sejakowatz {
196552a38012Sejakowatz 	return _sDefault;
196652a38012Sejakowatz }
196752a38012Sejakowatz 
196852a38012Sejakowatz 
196952a38012Sejakowatz status_t
197052a38012Sejakowatz BMediaRoster::SetTimeSourceFor(media_node_id node,
197152a38012Sejakowatz 							   media_node_id time_source)
197252a38012Sejakowatz {
1973aac800c2Sbeveloper 	CALLED();
197440f36b03Sbeveloper 	if (IS_INVALID_NODEID(node) || IS_INVALID_NODEID(time_source))
1975aac800c2Sbeveloper 		return B_BAD_VALUE;
1976aac800c2Sbeveloper 
1977aac800c2Sbeveloper 	media_node clone;
1978aac800c2Sbeveloper 	status_t rv, result;
1979aac800c2Sbeveloper 
19805917dd5bSbeveloper 	TRACE("BMediaRoster::SetTimeSourceFor: node %ld will be assigned time source %ld\n", node, time_source);
19815917dd5bSbeveloper 
19825917dd5bSbeveloper 	printf("BMediaRoster::SetTimeSourceFor: node %ld time source %ld enter\n", node, time_source);
19835917dd5bSbeveloper 
198486bce45bSbeveloper 	// we need to get a clone of the node to have a port id
1985aac800c2Sbeveloper 	rv = GetNodeFor(node, &clone);
1986aac800c2Sbeveloper 	if (rv != B_OK) {
19875ac4fbd7Sbeveloper 		ERROR("BMediaRoster::SetTimeSourceFor, GetNodeFor failed, node id %ld\n", node);
198852a38012Sejakowatz 		return B_ERROR;
198952a38012Sejakowatz 	}
199052a38012Sejakowatz 
199186bce45bSbeveloper 	// we just send the request to set time_source-id as timesource to the node,
199286bce45bSbeveloper 	// the NODE_SET_TIMESOURCE handler code will do the real assignment
1993aac800c2Sbeveloper 	result = B_OK;
1994aac800c2Sbeveloper 	node_set_timesource_command cmd;
1995aac800c2Sbeveloper 	cmd.timesource_id = time_source;
1996aac800c2Sbeveloper 	rv = SendToPort(clone.port, NODE_SET_TIMESOURCE, &cmd, sizeof(cmd));
1997aac800c2Sbeveloper 	if (rv != B_OK) {
19985ac4fbd7Sbeveloper 		ERROR("BMediaRoster::SetTimeSourceFor, sending NODE_SET_TIMESOURCE failed, node id %ld\n", node);
1999aac800c2Sbeveloper 		result = B_ERROR;
2000aac800c2Sbeveloper 	}
2001aac800c2Sbeveloper 
200260f15390Sbeveloper 	// we release the clone
2003aac800c2Sbeveloper 	rv = ReleaseNode(clone);
2004aac800c2Sbeveloper 	if (rv != B_OK) {
20055ac4fbd7Sbeveloper 		ERROR("BMediaRoster::SetTimeSourceFor, ReleaseNode failed, node id %ld\n", node);
2006aac800c2Sbeveloper 		result = B_ERROR;
2007aac800c2Sbeveloper 	}
2008aac800c2Sbeveloper 
20095917dd5bSbeveloper 	printf("BMediaRoster::SetTimeSourceFor: node %ld time source %ld leave\n", node, time_source);
20105917dd5bSbeveloper 
2011aac800c2Sbeveloper 	return result;
2012aac800c2Sbeveloper }
2013aac800c2Sbeveloper 
201452a38012Sejakowatz 
201552a38012Sejakowatz status_t
201652a38012Sejakowatz BMediaRoster::GetParameterWebFor(const media_node & node,
201752a38012Sejakowatz 								 BParameterWeb ** out_web)
201852a38012Sejakowatz {
201928ad138aSbeveloper 	CALLED();
202028ad138aSbeveloper 	if (out_web == NULL)
202128ad138aSbeveloper 		return B_BAD_VALUE;
202228ad138aSbeveloper 	if (IS_INVALID_NODE(node))
202328ad138aSbeveloper 		return B_MEDIA_BAD_NODE;
202428ad138aSbeveloper 	if ((node.kind & B_CONTROLLABLE) == 0)
202528ad138aSbeveloper 		return B_MEDIA_BAD_NODE;
202628ad138aSbeveloper 
202728ad138aSbeveloper 	controllable_get_parameter_web_request request;
202828ad138aSbeveloper 	controllable_get_parameter_web_reply reply;
202928ad138aSbeveloper 	int32 requestsize[] = {B_PAGE_SIZE, 4*B_PAGE_SIZE, 16*B_PAGE_SIZE, 64*B_PAGE_SIZE, 128*B_PAGE_SIZE, 256*B_PAGE_SIZE, 0};
203028ad138aSbeveloper 	int32 size;
203128ad138aSbeveloper 
203228ad138aSbeveloper 	// XXX it might be better to query the node for the (current) parameter size first
203328ad138aSbeveloper 	for (int i = 0; (size = requestsize[i]) != 0; i++) {
203428ad138aSbeveloper 		status_t rv;
203528ad138aSbeveloper 		area_id area;
203628ad138aSbeveloper 		void *data;
203728ad138aSbeveloper 		area = create_area("parameter web data", &data, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
203828ad138aSbeveloper 		if (area < B_OK) {
20395ac4fbd7Sbeveloper 			ERROR("BMediaRoster::GetParameterWebFor couldn't create area of size %ld\n", size);
204028ad138aSbeveloper 			return B_ERROR;
204128ad138aSbeveloper 		}
204228ad138aSbeveloper 		request.maxsize = size;
204328ad138aSbeveloper 		request.area = area;
204428ad138aSbeveloper 		rv = QueryPort(node.port, CONTROLLABLE_GET_PARAMETER_WEB, &request, sizeof(request), &reply, sizeof(reply));
204528ad138aSbeveloper 		if (rv != B_OK) {
20465ac4fbd7Sbeveloper 			ERROR("BMediaRoster::GetParameterWebFor CONTROLLABLE_GET_PARAMETER_WEB failed\n");
204728ad138aSbeveloper 			delete_area(area);
204828ad138aSbeveloper 			return B_ERROR;
204928ad138aSbeveloper 		}
205028ad138aSbeveloper 		if (reply.size == 0) {
205128ad138aSbeveloper 			// no parameter web available
205228ad138aSbeveloper 			// XXX should we return an error?
20535ac4fbd7Sbeveloper 			ERROR("BMediaRoster::GetParameterWebFor node %ld has no parameter web\n", node.node);
205428ad138aSbeveloper 			*out_web = new BParameterWeb();
205528ad138aSbeveloper 			delete_area(area);
205660f15390Sbeveloper 			return B_OK;
205752a38012Sejakowatz 		}
205828ad138aSbeveloper 		if (reply.size > 0) {
205928ad138aSbeveloper 			// we got a flattened parameter web!
206028ad138aSbeveloper 			*out_web = new BParameterWeb();
206128ad138aSbeveloper 
2062d91580cdSbeveloper 			printf("BMediaRoster::GetParameterWebFor Unflattening %ld bytes, 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx\n",
206328ad138aSbeveloper 				reply.size, ((uint32*)data)[0], ((uint32*)data)[1], ((uint32*)data)[2], ((uint32*)data)[3]);
206428ad138aSbeveloper 
206528ad138aSbeveloper 			rv = (*out_web)->Unflatten(reply.code, data, reply.size);
206628ad138aSbeveloper 			if (rv != B_OK) {
20675ac4fbd7Sbeveloper 				ERROR("BMediaRoster::GetParameterWebFor Unflatten failed, %s\n", strerror(rv));
206828ad138aSbeveloper 				delete_area(area);
206928ad138aSbeveloper 				delete *out_web;
207028ad138aSbeveloper 				return B_ERROR;
207128ad138aSbeveloper 			}
207228ad138aSbeveloper 			delete_area(area);
207328ad138aSbeveloper 			return B_OK;
207428ad138aSbeveloper 		}
207528ad138aSbeveloper 		delete_area(area);
207628ad138aSbeveloper 		ASSERT(reply.size == -1);
207728ad138aSbeveloper 		// parameter web data was too large
207828ad138aSbeveloper 		// loop and try a larger size
207928ad138aSbeveloper 	}
20805ac4fbd7Sbeveloper 	ERROR("BMediaRoster::GetParameterWebFor node %ld has no parameter web larger than %ld\n", node.node, size);
208128ad138aSbeveloper 	return B_ERROR;
208228ad138aSbeveloper }
208352a38012Sejakowatz 
208452a38012Sejakowatz 
208552a38012Sejakowatz status_t
208652a38012Sejakowatz BMediaRoster::StartControlPanel(const media_node & node,
208752a38012Sejakowatz 								BMessenger * out_messenger)
208852a38012Sejakowatz {
208952a38012Sejakowatz 	UNIMPLEMENTED();
209052a38012Sejakowatz 	return B_ERROR;
209152a38012Sejakowatz }
209252a38012Sejakowatz 
209352a38012Sejakowatz 
209452a38012Sejakowatz status_t
209552a38012Sejakowatz BMediaRoster::GetDormantNodes(dormant_node_info * out_info,
209652a38012Sejakowatz 							  int32 * io_count,
209752a38012Sejakowatz 							  const media_format * has_input /* = NULL */,
209852a38012Sejakowatz 							  const media_format * has_output /* = NULL */,
209952a38012Sejakowatz 							  const char * name /* = NULL */,
210052a38012Sejakowatz 							  uint64 require_kinds /* = NULL */,
210152a38012Sejakowatz 							  uint64 deny_kinds /* = NULL */)
210252a38012Sejakowatz {
210352a38012Sejakowatz 	CALLED();
210452a38012Sejakowatz 	if (out_info == NULL)
210552a38012Sejakowatz 		return B_BAD_VALUE;
210652a38012Sejakowatz 	if (io_count == NULL)
210752a38012Sejakowatz 		return B_BAD_VALUE;
210852a38012Sejakowatz 	if (*io_count <= 0)
210952a38012Sejakowatz 		return B_BAD_VALUE;
211052a38012Sejakowatz 
211152a38012Sejakowatz 	xfer_server_get_dormant_nodes msg;
211252a38012Sejakowatz 	port_id port;
211352a38012Sejakowatz 	status_t rv;
211452a38012Sejakowatz 
21154295907bSbeveloper 	port = find_port(MEDIA_SERVER_PORT_NAME);
211652a38012Sejakowatz 	if (port <= B_OK)
211752a38012Sejakowatz 		return B_ERROR;
211852a38012Sejakowatz 
211952a38012Sejakowatz 	msg.maxcount = *io_count;
212052a38012Sejakowatz 	msg.has_input = (bool) has_input;
212152a38012Sejakowatz 	if (has_input)
212252a38012Sejakowatz 		msg.inputformat = *has_input; // XXX we should not make a flat copy of media_format
212352a38012Sejakowatz 	msg.has_output = (bool) has_output;
212452a38012Sejakowatz 	if (has_output)
212552a38012Sejakowatz 		msg.outputformat = *has_output;; // XXX we should not make a flat copy of media_format
212652a38012Sejakowatz 	msg.has_name = (bool) name;
212752a38012Sejakowatz 	if (name) {
21289e9417d2Sbeveloper 		int len = strlen(name);
21299e9417d2Sbeveloper 		len = min_c(len, (int)sizeof(msg.name) - 1);
213052a38012Sejakowatz 		memcpy(msg.name, name, len);
213152a38012Sejakowatz 		msg.name[len] = 0;
213252a38012Sejakowatz 	}
213352a38012Sejakowatz 	msg.require_kinds = require_kinds;
213452a38012Sejakowatz 	msg.deny_kinds = deny_kinds;
213552a38012Sejakowatz 	msg.reply_port = _PortPool->GetPort();
213652a38012Sejakowatz 
213752a38012Sejakowatz 	rv = write_port(port, SERVER_GET_DORMANT_NODES, &msg, sizeof(msg));
213852a38012Sejakowatz 	if (rv != B_OK) {
213952a38012Sejakowatz 		_PortPool->PutPort(msg.reply_port);
214052a38012Sejakowatz 		return rv;
214152a38012Sejakowatz 	}
214252a38012Sejakowatz 
214352a38012Sejakowatz 	xfer_server_get_dormant_nodes_reply reply;
214452a38012Sejakowatz 	int32 code;
214552a38012Sejakowatz 
214652a38012Sejakowatz 	rv = read_port(msg.reply_port, &code, &reply, sizeof(reply));
214752a38012Sejakowatz 	if (rv < B_OK) {
214852a38012Sejakowatz 		_PortPool->PutPort(msg.reply_port);
214952a38012Sejakowatz 		return rv;
215052a38012Sejakowatz 	}
215152a38012Sejakowatz 
215252a38012Sejakowatz 	*io_count = reply.count;
215352a38012Sejakowatz 
215452a38012Sejakowatz 	if (*io_count > 0) {
215552a38012Sejakowatz 		rv = read_port(msg.reply_port, &code, out_info, *io_count * sizeof(dormant_node_info));
215652a38012Sejakowatz 		if (rv < B_OK)
215752a38012Sejakowatz 			reply.result = rv;
215852a38012Sejakowatz 	}
215952a38012Sejakowatz 	_PortPool->PutPort(msg.reply_port);
216052a38012Sejakowatz 
216152a38012Sejakowatz 	return reply.result;
216252a38012Sejakowatz }
216352a38012Sejakowatz 
21648b04ffc1Sbeveloper /* This function is used to do the real work of instantiating a dormant node. It is either
21658b04ffc1Sbeveloper  * called by the media_addon_server to instantiate a global node, or it gets called from
21668b04ffc1Sbeveloper  * BMediaRoster::InstantiateDormantNode() to create a local one.
21678b04ffc1Sbeveloper  *
21688b04ffc1Sbeveloper  * Checks concerning global/local are not done here.
21698b04ffc1Sbeveloper  */
217052a38012Sejakowatz status_t
217154187cc6Sbeveloper BMediaRosterEx::InstantiateDormantNode(media_addon_id addonid, int32 flavorid, team_id creator, media_node *out_node)
217252a38012Sejakowatz {
217354187cc6Sbeveloper 	// This function is always called from the correct context, if the node
217454187cc6Sbeveloper 	// is supposed to be global, it is called from the media_addon_server.
217554187cc6Sbeveloper 
217652a38012Sejakowatz 	// if B_FLAVOR_IS_GLOBAL, we need to use the BMediaAddOn object that
217752a38012Sejakowatz 	// resides in the media_addon_server
217852a38012Sejakowatz 
21798b04ffc1Sbeveloper 	// RegisterNode() must be called for nodes instantiated from add-ons,
21808b04ffc1Sbeveloper 	// since the media kit warrants that it's done automatically.
218152a38012Sejakowatz 
218254187cc6Sbeveloper 	// addonid		Indicates the ID number of the media add-on in which the node resides.
218354187cc6Sbeveloper 	// flavorid		Indicates the internal ID number that the add-on uses to identify the flavor,
218454187cc6Sbeveloper 	//				this is the number that was published by BMediaAddOn::GetFlavorAt() in the
21858b04ffc1Sbeveloper 	//				flavor_info::internal_id field.
218654187cc6Sbeveloper 	// creator		The creator team is -1 if nodes are created locally. If created globally,
218754187cc6Sbeveloper 	//				it will contain (while called in media_addon_server context) the team-id of
218854187cc6Sbeveloper 	// 				the team that requested the instantiation.
21898b04ffc1Sbeveloper 
219060f15390Sbeveloper 	TRACE("BMediaRosterEx::InstantiateDormantNode: addon-id %ld, flavor_id %ld\n", addonid, flavorid);
21918b04ffc1Sbeveloper 
21928b04ffc1Sbeveloper 	// Get flavor_info from the server
21938b04ffc1Sbeveloper 	dormant_flavor_info node_info;
21948c6a6096Sbeveloper 	status_t rv;
21958b04ffc1Sbeveloper 	rv = GetDormantFlavorInfo(addonid, flavorid, &node_info);
21968b04ffc1Sbeveloper 	if (rv != B_OK) {
21975ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::InstantiateDormantNode error: failed to get dormant_flavor_info for addon-id %ld, flavor-id %ld\n", addonid, flavorid);
219852a38012Sejakowatz 		return B_ERROR;
219952a38012Sejakowatz 	}
22008b04ffc1Sbeveloper 
2201908eaf85Sbeveloper 	//ASSERT(node_info.internal_id == flavorid);
2202908eaf85Sbeveloper 	if (node_info.internal_id != flavorid) {
22034d2d96e0Sbeveloper 		ERROR("############# BMediaRosterEx::InstantiateDormantNode failed: ID mismatch for addon-id %ld, flavor-id %ld, node_info.internal_id %ld, node_info.name %s\n", addonid, flavorid, node_info.internal_id, node_info.name);
2204908eaf85Sbeveloper 		return B_ERROR;
2205908eaf85Sbeveloper 	}
22068b04ffc1Sbeveloper 
22078b04ffc1Sbeveloper 	// load the BMediaAddOn object
22088b04ffc1Sbeveloper 	BMediaAddOn *addon;
22098b04ffc1Sbeveloper 	addon = _DormantNodeManager->GetAddon(addonid);
22108b04ffc1Sbeveloper 	if (!addon) {
22115ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::InstantiateDormantNode: GetAddon failed\n");
22128b04ffc1Sbeveloper 		return B_ERROR;
22138b04ffc1Sbeveloper 	}
22148b04ffc1Sbeveloper 
221554187cc6Sbeveloper 	// Now we need to try to increment the use count of this addon flavor
221654187cc6Sbeveloper 	// in the server. This can fail if the total number instances of this
221754187cc6Sbeveloper 	// flavor is limited.
221873794717Sbeveloper 	rv = IncrementAddonFlavorInstancesCount(addonid, flavorid);
221954187cc6Sbeveloper 	if (rv != B_OK) {
22205ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::InstantiateDormantNode error: can't create more nodes for addon-id %ld, flavor-id %ld\n", addonid, flavorid);
222154187cc6Sbeveloper 		// Put the addon back into the pool
222254187cc6Sbeveloper 		_DormantNodeManager->PutAddon(addonid);
222354187cc6Sbeveloper 		return B_ERROR;
222454187cc6Sbeveloper 	}
222554187cc6Sbeveloper 
22268b04ffc1Sbeveloper 	BMessage config;
222754187cc6Sbeveloper 	rv = LoadNodeConfiguration(addonid, flavorid, &config);
222854187cc6Sbeveloper 	if (rv != B_OK) {
22295ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::InstantiateDormantNode: couldn't load configuration for addon-id %ld, flavor-id %ld\n", addonid, flavorid);
223054187cc6Sbeveloper 		// do not return, this is a minor problem, not a reason to fail
223154187cc6Sbeveloper 	}
22328b04ffc1Sbeveloper 
22338b04ffc1Sbeveloper 	BMediaNode *node;
22348b04ffc1Sbeveloper 	status_t out_error;
22358b04ffc1Sbeveloper 
223654187cc6Sbeveloper 	out_error = B_OK;
22378b04ffc1Sbeveloper 	node = addon->InstantiateNodeFor(&node_info, &config, &out_error);
223816b7eea4Sbeveloper 	if (!node) {
22395ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::InstantiateDormantNode: InstantiateNodeFor failed\n");
224054187cc6Sbeveloper 		// Put the addon back into the pool
22418b04ffc1Sbeveloper 		_DormantNodeManager->PutAddon(addonid);
224254187cc6Sbeveloper 		// We must decrement the use count of this addon flavor in the
224354187cc6Sbeveloper 		// server to compensate the increment done in the beginning.
224473794717Sbeveloper 		rv = DecrementAddonFlavorInstancesCount(addonid, flavorid);
224554187cc6Sbeveloper 		if (rv != B_OK) {
22465ac4fbd7Sbeveloper 			ERROR("BMediaRosterEx::InstantiateDormantNode: DecrementAddonFlavorInstancesCount failed\n");
224716b7eea4Sbeveloper 		}
224854187cc6Sbeveloper 		return (out_error != B_OK) ? out_error : B_ERROR;
224954187cc6Sbeveloper 	}
225054187cc6Sbeveloper 
225154187cc6Sbeveloper 	rv = RegisterNode(node, addonid, flavorid);
22528c6a6096Sbeveloper 	if (rv != B_OK) {
22535ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::InstantiateDormantNode: RegisterNode failed\n");
22548c6a6096Sbeveloper 		delete node;
225554187cc6Sbeveloper 		// Put the addon back into the pool
22568b04ffc1Sbeveloper 		_DormantNodeManager->PutAddon(addonid);
225754187cc6Sbeveloper 		// We must decrement the use count of this addon flavor in the
225854187cc6Sbeveloper 		// server to compensate the increment done in the beginning.
225973794717Sbeveloper 		rv = DecrementAddonFlavorInstancesCount(addonid, flavorid);
226054187cc6Sbeveloper 		if (rv != B_OK) {
22615ac4fbd7Sbeveloper 			ERROR("BMediaRosterEx::InstantiateDormantNode: DecrementAddonFlavorInstancesCount failed\n");
226254187cc6Sbeveloper 		}
22638c6a6096Sbeveloper 		return B_ERROR;
22648c6a6096Sbeveloper 	}
22658c6a6096Sbeveloper 
226654187cc6Sbeveloper 	if (creator != -1) {
226754187cc6Sbeveloper 		// send a message to the server to assign team "creator" as creator of node "node->ID()"
226854187cc6Sbeveloper 		printf("!!! BMediaRosterEx::InstantiateDormantNode assigning team %ld as creator of node %ld\n", creator, node->ID());
226954187cc6Sbeveloper 		rv = MediaRosterEx(this)->SetNodeCreator(node->ID(), creator);
227054187cc6Sbeveloper 		if (rv != B_OK) {
22715ac4fbd7Sbeveloper 			ERROR("BMediaRosterEx::InstantiateDormantNode failed to assign team %ld as creator of node %ld\n", creator, node->ID());
227254187cc6Sbeveloper 			// do not return, this is a minor problem, not a reason to fail
227354187cc6Sbeveloper 		}
227454187cc6Sbeveloper 	}
227554187cc6Sbeveloper 
227654187cc6Sbeveloper 	// RegisterNode() does remember the add-on id in the server
227754187cc6Sbeveloper 	// and UnregisterNode() will call DormantNodeManager::PutAddon()
227854187cc6Sbeveloper 	// when the node is unregistered.
22798c6a6096Sbeveloper 
228016b7eea4Sbeveloper 	*out_node = node->Node();
2281cf4e2277Sbeveloper 
228260f15390Sbeveloper 	TRACE("BMediaRosterEx::InstantiateDormantNode: addon-id %ld, flavor_id %ld instanciated as node %ld, port %ld in team %ld\n", addonid, flavorid, out_node->node, out_node->port, team);
2283cf4e2277Sbeveloper 
228416b7eea4Sbeveloper 	return B_OK;
228516b7eea4Sbeveloper }
228652a38012Sejakowatz 
228752a38012Sejakowatz 
228852a38012Sejakowatz status_t
22898b04ffc1Sbeveloper BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info,
22908b04ffc1Sbeveloper 									 media_node * out_node,
22918b04ffc1Sbeveloper 									 uint32 flags /* currently 0 or B_FLAVOR_IS_GLOBAL or B_FLAVOR_IS_LOCAL */ )
22928b04ffc1Sbeveloper {
22938b04ffc1Sbeveloper 	CALLED();
22948b04ffc1Sbeveloper 	if (out_node == 0)
22958b04ffc1Sbeveloper 		return B_BAD_VALUE;
22968b04ffc1Sbeveloper 	if (in_info.addon <= 0) {
22975ac4fbd7Sbeveloper 		ERROR("BMediaRoster::InstantiateDormantNode error: addon-id %ld invalid.\n", in_info.addon);
22988b04ffc1Sbeveloper 		return B_BAD_VALUE;
22998b04ffc1Sbeveloper 	}
23008b04ffc1Sbeveloper 
2301d91580cdSbeveloper 	printf("BMediaRoster::InstantiateDormantNode: addon-id %ld, flavor_id %ld, flags 0x%lX\n", in_info.addon, in_info.flavor_id, flags);
23028b04ffc1Sbeveloper 
23038b04ffc1Sbeveloper 	// Get flavor_info from the server
23048b04ffc1Sbeveloper 	// XXX this is a little overhead, as we get the full blown dormant_flavor_info,
23058b04ffc1Sbeveloper 	// XXX but only need the flags.
23068b04ffc1Sbeveloper 	dormant_flavor_info node_info;
23078b04ffc1Sbeveloper 	status_t rv;
23088b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetDormantFlavorInfo(in_info.addon, in_info.flavor_id, &node_info);
23098b04ffc1Sbeveloper 	if (rv != B_OK) {
23105ac4fbd7Sbeveloper 		ERROR("BMediaRoster::InstantiateDormantNode: failed to get dormant_flavor_info for addon-id %ld, flavor-id %ld\n", in_info.addon, in_info.flavor_id);
2311626824eaSbeveloper 		return B_NAME_NOT_FOUND;
23128b04ffc1Sbeveloper 	}
23138b04ffc1Sbeveloper 
23148b04ffc1Sbeveloper 	ASSERT(node_info.internal_id == in_info.flavor_id);
23158b04ffc1Sbeveloper 
2316d91580cdSbeveloper 	printf("BMediaRoster::InstantiateDormantNode: name \"%s\", info \"%s\", flavor_flags 0x%lX, internal_id %ld, possible_count %ld\n",
23178b04ffc1Sbeveloper 		node_info.name, node_info.info, node_info.flavor_flags, node_info.internal_id, node_info.possible_count);
23188b04ffc1Sbeveloper 
23198b04ffc1Sbeveloper 	#if DEBUG
23208b04ffc1Sbeveloper 		if (flags & B_FLAVOR_IS_LOCAL)
23218b04ffc1Sbeveloper 			printf("BMediaRoster::InstantiateDormantNode: caller requested B_FLAVOR_IS_LOCAL\n");
23228b04ffc1Sbeveloper 		if (flags & B_FLAVOR_IS_GLOBAL)
23238b04ffc1Sbeveloper 			printf("BMediaRoster::InstantiateDormantNode: caller requested B_FLAVOR_IS_GLOBAL\n");
23248b04ffc1Sbeveloper 		if (node_info.flavor_flags & B_FLAVOR_IS_LOCAL)
23258b04ffc1Sbeveloper 			printf("BMediaRoster::InstantiateDormantNode: node requires B_FLAVOR_IS_LOCAL\n");
23268b04ffc1Sbeveloper 		if (node_info.flavor_flags & B_FLAVOR_IS_GLOBAL)
23278b04ffc1Sbeveloper 			printf("BMediaRoster::InstantiateDormantNode: node requires B_FLAVOR_IS_GLOBAL\n");
23288b04ffc1Sbeveloper 	#endif
23298b04ffc1Sbeveloper 
23308b04ffc1Sbeveloper 	// Make sure that flags demanded by the dormant node and those requested
23318b04ffc1Sbeveloper 	// by the caller are not incompatible.
23328b04ffc1Sbeveloper 	if ((node_info.flavor_flags & B_FLAVOR_IS_GLOBAL) && (flags & B_FLAVOR_IS_LOCAL)) {
23335ac4fbd7Sbeveloper 		ERROR("BMediaRoster::InstantiateDormantNode: requested B_FLAVOR_IS_LOCAL, but dormant node has B_FLAVOR_IS_GLOBAL\n");
2334626824eaSbeveloper 		return B_NAME_NOT_FOUND;
23358b04ffc1Sbeveloper 	}
23368b04ffc1Sbeveloper 	if ((node_info.flavor_flags & B_FLAVOR_IS_LOCAL) && (flags & B_FLAVOR_IS_GLOBAL)) {
23375ac4fbd7Sbeveloper 		ERROR("BMediaRoster::InstantiateDormantNode: requested B_FLAVOR_IS_GLOBAL, but dormant node has B_FLAVOR_IS_LOCAL\n");
2338626824eaSbeveloper 		return B_NAME_NOT_FOUND;
23398b04ffc1Sbeveloper 	}
234054187cc6Sbeveloper 
23418b04ffc1Sbeveloper 	// If either the node, or the caller requested to make the instance global
23428b04ffc1Sbeveloper 	// we will do it by forwarding this request into the media_addon_server, which
23438b04ffc1Sbeveloper 	// in turn will call BMediaRosterEx::InstantiateDormantNode to create the node
23448b04ffc1Sbeveloper 	// there and make it globally available.
23458b04ffc1Sbeveloper 	if ((node_info.flavor_flags & B_FLAVOR_IS_GLOBAL) || (flags & B_FLAVOR_IS_GLOBAL)) {
23468b04ffc1Sbeveloper 
2347cf4e2277Sbeveloper 		printf("BMediaRoster::InstantiateDormantNode: creating global object in media_addon_server\n");
2348cf4e2277Sbeveloper 
23498b04ffc1Sbeveloper 		addonserver_instantiate_dormant_node_request request;
23508b04ffc1Sbeveloper 		addonserver_instantiate_dormant_node_reply reply;
23518b04ffc1Sbeveloper 		request.addonid = in_info.addon;
23528b04ffc1Sbeveloper 		request.flavorid = in_info.flavor_id;
235354187cc6Sbeveloper 		request.creator_team = team; // creator team is allowed to also release global nodes
23548b04ffc1Sbeveloper 		rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request, sizeof(request), &reply, sizeof(reply));
23558b04ffc1Sbeveloper 		if (rv == B_OK) {
23568b04ffc1Sbeveloper 			*out_node = reply.node;
23578b04ffc1Sbeveloper 		}
23588b04ffc1Sbeveloper 
23598b04ffc1Sbeveloper 	} else {
23608b04ffc1Sbeveloper 
236154187cc6Sbeveloper 		// creator team = -1, as this is a local node
2362626824eaSbeveloper 		rv = MediaRosterEx(this)->InstantiateDormantNode(in_info.addon, in_info.flavor_id, -1, out_node);
2363626824eaSbeveloper 
23648b04ffc1Sbeveloper 	}
2365626824eaSbeveloper 	if (rv != B_OK) {
2366626824eaSbeveloper 		*out_node = media_node::null;
2367626824eaSbeveloper 		return B_NAME_NOT_FOUND;
2368626824eaSbeveloper 	}
2369626824eaSbeveloper 	return B_OK;
23708b04ffc1Sbeveloper }
23718b04ffc1Sbeveloper 
23728b04ffc1Sbeveloper 
23738b04ffc1Sbeveloper status_t
23748b04ffc1Sbeveloper BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info,
23758b04ffc1Sbeveloper 									 media_node * out_node)
23768b04ffc1Sbeveloper {
23778b04ffc1Sbeveloper 	return InstantiateDormantNode(in_info, out_node, 0);
23788b04ffc1Sbeveloper }
23798b04ffc1Sbeveloper 
23808b04ffc1Sbeveloper 
23818b04ffc1Sbeveloper status_t
238252a38012Sejakowatz BMediaRoster::GetDormantNodeFor(const media_node & node,
238352a38012Sejakowatz 								dormant_node_info * out_info)
238452a38012Sejakowatz {
238585dfab2bSbeveloper 	CALLED();
238685dfab2bSbeveloper 	if (out_info == NULL)
238785dfab2bSbeveloper 		return B_BAD_VALUE;
238840f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
238985dfab2bSbeveloper 		return B_MEDIA_BAD_NODE;
239052a38012Sejakowatz 
239185dfab2bSbeveloper 	server_get_dormant_node_for_request request;
239285dfab2bSbeveloper 	server_get_dormant_node_for_reply reply;
239385dfab2bSbeveloper 	status_t rv;
239485dfab2bSbeveloper 
239585dfab2bSbeveloper 	request.node = node;
239685dfab2bSbeveloper 
23971299bfb2Sbeveloper 	rv = QueryServer(SERVER_GET_DORMANT_NODE_FOR, &request, sizeof(request), &reply, sizeof(reply));
239885dfab2bSbeveloper 	if (rv != B_OK)
239985dfab2bSbeveloper 		return rv;
240085dfab2bSbeveloper 
240185dfab2bSbeveloper 	*out_info = reply.node_info;
240285dfab2bSbeveloper 	return B_OK;
240352a38012Sejakowatz }
240452a38012Sejakowatz 
240552a38012Sejakowatz status_t
24068b04ffc1Sbeveloper BMediaRosterEx::GetDormantFlavorInfo(media_addon_id addonid,
24078b04ffc1Sbeveloper 									  int32 flavorid,
240852a38012Sejakowatz 									  dormant_flavor_info * out_flavor)
240952a38012Sejakowatz {
241052a38012Sejakowatz 	CALLED();
24119bedd42cSbeveloper 	if (out_flavor == NULL)
24129bedd42cSbeveloper 		return B_BAD_VALUE;
241352a38012Sejakowatz 
241452a38012Sejakowatz 	xfer_server_get_dormant_flavor_info msg;
241552a38012Sejakowatz 	xfer_server_get_dormant_flavor_info_reply *reply;
241652a38012Sejakowatz 	port_id port;
241752a38012Sejakowatz 	status_t rv;
241852a38012Sejakowatz 	int32 code;
241952a38012Sejakowatz 
24204295907bSbeveloper 	port = find_port(MEDIA_SERVER_PORT_NAME);
242152a38012Sejakowatz 	if (port <= B_OK)
242252a38012Sejakowatz 		return B_ERROR;
242352a38012Sejakowatz 
242452a38012Sejakowatz 	reply = (xfer_server_get_dormant_flavor_info_reply *) malloc(16000);
242552a38012Sejakowatz 	if (reply == 0)
242652a38012Sejakowatz 		return B_ERROR;
242752a38012Sejakowatz 
24288b04ffc1Sbeveloper 	msg.addon 		= addonid;
24298b04ffc1Sbeveloper 	msg.flavor_id 	= flavorid;
243052a38012Sejakowatz 	msg.reply_port 	= _PortPool->GetPort();
243152a38012Sejakowatz 	rv = write_port(port, SERVER_GET_DORMANT_FLAVOR_INFO, &msg, sizeof(msg));
243252a38012Sejakowatz 	if (rv != B_OK) {
243352a38012Sejakowatz 		free(reply);
243452a38012Sejakowatz 		_PortPool->PutPort(msg.reply_port);
243552a38012Sejakowatz 		return rv;
243652a38012Sejakowatz 	}
243752a38012Sejakowatz 	rv = read_port(msg.reply_port, &code, reply, 16000);
243852a38012Sejakowatz 	_PortPool->PutPort(msg.reply_port);
243952a38012Sejakowatz 
244052a38012Sejakowatz 	if (rv < B_OK) {
244152a38012Sejakowatz 		free(reply);
244252a38012Sejakowatz 		return rv;
244352a38012Sejakowatz 	}
244452a38012Sejakowatz 
244552a38012Sejakowatz 	if (reply->result == B_OK)
244652a38012Sejakowatz 		rv = out_flavor->Unflatten(reply->dfi_type, &reply->dfi, reply->dfi_size);
244752a38012Sejakowatz 	else
244852a38012Sejakowatz 		rv = reply->result;
244952a38012Sejakowatz 
245052a38012Sejakowatz 	free(reply);
245152a38012Sejakowatz 	return rv;
245252a38012Sejakowatz }
245352a38012Sejakowatz 
24548b04ffc1Sbeveloper status_t
24558b04ffc1Sbeveloper BMediaRoster::GetDormantFlavorInfoFor(const dormant_node_info & in_dormant,
24568b04ffc1Sbeveloper 									  dormant_flavor_info * out_flavor)
24578b04ffc1Sbeveloper {
24588b04ffc1Sbeveloper 	return MediaRosterEx(this)->GetDormantFlavorInfo(in_dormant.addon, in_dormant.flavor_id, out_flavor);
24598b04ffc1Sbeveloper }
246052a38012Sejakowatz 
246160f15390Sbeveloper // Reports in outLatency the maximum latency found downstream from
246260f15390Sbeveloper // the specified BBufferProducer, producer, given the current connections.
246352a38012Sejakowatz status_t
246452a38012Sejakowatz BMediaRoster::GetLatencyFor(const media_node & producer,
246552a38012Sejakowatz 							bigtime_t * out_latency)
246652a38012Sejakowatz {
246760f15390Sbeveloper 	CALLED();
246860f15390Sbeveloper 	if (out_latency == NULL)
246960f15390Sbeveloper 		return B_BAD_VALUE;
247060f15390Sbeveloper 	if (IS_INVALID_NODE(producer))
247160f15390Sbeveloper 		return B_MEDIA_BAD_NODE;
247260f15390Sbeveloper 	if ((producer.kind & B_BUFFER_PRODUCER) == 0)
247360f15390Sbeveloper 		return B_MEDIA_BAD_NODE;
247460f15390Sbeveloper 
247560f15390Sbeveloper 	producer_get_latency_request request;
247660f15390Sbeveloper 	producer_get_latency_reply reply;
247760f15390Sbeveloper 	status_t rv;
247860f15390Sbeveloper 
247960f15390Sbeveloper 	rv = QueryPort(producer.port, PRODUCER_GET_LATENCY, &request, sizeof(request), &reply, sizeof(reply));
248060f15390Sbeveloper 	if (rv != B_OK)
248160f15390Sbeveloper 		return rv;
248260f15390Sbeveloper 
248360f15390Sbeveloper 	*out_latency = reply.latency;
248460f15390Sbeveloper 
2485*ab9afde3SMarcus Overhagen //	printf("BMediaRoster::GetLatencyFor producer %ld has maximum latency %Ld\n", producer.node, *out_latency);
2486aac800c2Sbeveloper 	return B_OK;
248752a38012Sejakowatz }
248852a38012Sejakowatz 
248952a38012Sejakowatz 
249052a38012Sejakowatz status_t
249152a38012Sejakowatz BMediaRoster::GetInitialLatencyFor(const media_node & producer,
249252a38012Sejakowatz 								   bigtime_t * out_latency,
2493aac800c2Sbeveloper 								   uint32 * out_flags /* = NULL */)
249452a38012Sejakowatz {
2495b65a0ac5SJérôme Duval 	CALLED();
2496b65a0ac5SJérôme Duval 	if (out_latency == NULL)
2497b65a0ac5SJérôme Duval 		return B_BAD_VALUE;
2498b65a0ac5SJérôme Duval 	if (IS_INVALID_NODE(producer))
2499b65a0ac5SJérôme Duval 		return B_MEDIA_BAD_NODE;
2500b65a0ac5SJérôme Duval 	if ((producer.kind & B_BUFFER_PRODUCER) == 0)
2501b65a0ac5SJérôme Duval 		return B_MEDIA_BAD_NODE;
2502b65a0ac5SJérôme Duval 
2503b65a0ac5SJérôme Duval 	producer_get_initial_latency_request request;
2504b65a0ac5SJérôme Duval 	producer_get_initial_latency_reply reply;
2505b65a0ac5SJérôme Duval 	status_t rv;
2506b65a0ac5SJérôme Duval 
2507b65a0ac5SJérôme Duval 	rv = QueryPort(producer.port, PRODUCER_GET_INITIAL_LATENCY, &request, sizeof(request), &reply, sizeof(reply));
2508b65a0ac5SJérôme Duval 	if (rv != B_OK)
2509b65a0ac5SJérôme Duval 		return rv;
2510b65a0ac5SJérôme Duval 
2511b65a0ac5SJérôme Duval 	*out_latency = reply.initial_latency;
2512aac800c2Sbeveloper 	if (out_flags)
2513b65a0ac5SJérôme Duval 		*out_flags = reply.flags;
2514b65a0ac5SJérôme Duval 
2515b65a0ac5SJérôme Duval 	printf("BMediaRoster::GetInitialLatencyFor producer %ld has maximum initial latency %Ld\n", producer.node, *out_latency);
2516aac800c2Sbeveloper 	return B_OK;
251752a38012Sejakowatz }
251852a38012Sejakowatz 
251952a38012Sejakowatz 
252052a38012Sejakowatz status_t
252152a38012Sejakowatz BMediaRoster::GetStartLatencyFor(const media_node & time_source,
252252a38012Sejakowatz 								 bigtime_t * out_latency)
252352a38012Sejakowatz {
2524fc8b28b6SJérôme Duval 	CALLED();
2525fc8b28b6SJérôme Duval 	if (out_latency == NULL)
2526fc8b28b6SJérôme Duval 		return B_BAD_VALUE;
2527fc8b28b6SJérôme Duval 	if (IS_INVALID_NODE(time_source))
2528fc8b28b6SJérôme Duval 		return B_MEDIA_BAD_NODE;
2529fc8b28b6SJérôme Duval 	if ((time_source.kind & B_TIME_SOURCE) == 0)
2530fc8b28b6SJérôme Duval 		return B_MEDIA_BAD_NODE;
2531fc8b28b6SJérôme Duval 
2532fc8b28b6SJérôme Duval 	timesource_get_start_latency_request request;
2533fc8b28b6SJérôme Duval 	timesource_get_start_latency_reply reply;
2534fc8b28b6SJérôme Duval 	status_t rv;
2535fc8b28b6SJérôme Duval 
2536fc8b28b6SJérôme Duval 	rv = QueryPort(time_source.port, TIMESOURCE_GET_START_LATENCY, &request, sizeof(request), &reply, sizeof(reply));
2537fc8b28b6SJérôme Duval 	if (rv != B_OK)
2538fc8b28b6SJérôme Duval 		return rv;
2539fc8b28b6SJérôme Duval 
2540fc8b28b6SJérôme Duval 	*out_latency = reply.start_latency;
2541fc8b28b6SJérôme Duval 
2542fc8b28b6SJérôme Duval 	printf("BMediaRoster::GetStartLatencyFor timesource %ld has maximum initial latency %Ld\n", time_source.node, *out_latency);
2543aac800c2Sbeveloper 	return B_OK;
254452a38012Sejakowatz }
254552a38012Sejakowatz 
254652a38012Sejakowatz 
254752a38012Sejakowatz status_t
254852a38012Sejakowatz BMediaRoster::GetFileFormatsFor(const media_node & file_interface,
254952a38012Sejakowatz 								media_file_format * out_formats,
255052a38012Sejakowatz 								int32 * io_num_infos)
255152a38012Sejakowatz {
255252a38012Sejakowatz 	UNIMPLEMENTED();
255352a38012Sejakowatz 	return B_ERROR;
255452a38012Sejakowatz }
255552a38012Sejakowatz 
255652a38012Sejakowatz 
255752a38012Sejakowatz status_t
255852a38012Sejakowatz BMediaRoster::SetRefFor(const media_node & file_interface,
255952a38012Sejakowatz 						const entry_ref & file,
256052a38012Sejakowatz 						bool create_and_truncate,
256152a38012Sejakowatz 						bigtime_t * out_length)	/* if create is false */
256252a38012Sejakowatz {
256352a38012Sejakowatz 	UNIMPLEMENTED();
256452a38012Sejakowatz 	return B_ERROR;
256552a38012Sejakowatz }
256652a38012Sejakowatz 
256752a38012Sejakowatz 
256852a38012Sejakowatz status_t
256952a38012Sejakowatz BMediaRoster::GetRefFor(const media_node & node,
257052a38012Sejakowatz 						entry_ref * out_file,
257152a38012Sejakowatz 						BMimeType * mime_type)
257252a38012Sejakowatz {
257352a38012Sejakowatz 	UNIMPLEMENTED();
257452a38012Sejakowatz 	return B_ERROR;
257552a38012Sejakowatz }
257652a38012Sejakowatz 
257752a38012Sejakowatz 
257852a38012Sejakowatz status_t
257952a38012Sejakowatz BMediaRoster::SniffRefFor(const media_node & file_interface,
258052a38012Sejakowatz 						  const entry_ref & file,
258152a38012Sejakowatz 						  BMimeType * mime_type,
258252a38012Sejakowatz 						  float * out_capability)
258352a38012Sejakowatz {
258452a38012Sejakowatz 	UNIMPLEMENTED();
258552a38012Sejakowatz 	return B_ERROR;
258652a38012Sejakowatz }
258752a38012Sejakowatz 
258852a38012Sejakowatz 
258952a38012Sejakowatz /* This is the generic "here's a file, now can someone please play it" interface */
259052a38012Sejakowatz status_t
259152a38012Sejakowatz BMediaRoster::SniffRef(const entry_ref & file,
259252a38012Sejakowatz 					   uint64 require_node_kinds,		/* if you need an EntityInterface or BufferConsumer or something */
259352a38012Sejakowatz 					   dormant_node_info * out_node,
259452a38012Sejakowatz 					   BMimeType * mime_type)
259552a38012Sejakowatz {
259652a38012Sejakowatz 	UNIMPLEMENTED();
259752a38012Sejakowatz 	return B_ERROR;
259852a38012Sejakowatz }
259952a38012Sejakowatz 
260052a38012Sejakowatz 
260152a38012Sejakowatz status_t
260252a38012Sejakowatz BMediaRoster::GetDormantNodeForType(const BMimeType & type,
260352a38012Sejakowatz 									uint64 require_node_kinds,
260452a38012Sejakowatz 									dormant_node_info * out_node)
260552a38012Sejakowatz {
260652a38012Sejakowatz 	UNIMPLEMENTED();
260752a38012Sejakowatz 	return B_ERROR;
260852a38012Sejakowatz }
260952a38012Sejakowatz 
261052a38012Sejakowatz 
261152a38012Sejakowatz status_t
261252a38012Sejakowatz BMediaRoster::GetReadFileFormatsFor(const dormant_node_info & in_node,
261352a38012Sejakowatz 									media_file_format * out_read_formats,
261452a38012Sejakowatz 									int32 in_read_count,
261552a38012Sejakowatz 									int32 * out_read_count)
261652a38012Sejakowatz {
261752a38012Sejakowatz 	UNIMPLEMENTED();
261852a38012Sejakowatz 	return B_ERROR;
261952a38012Sejakowatz }
262052a38012Sejakowatz 
262152a38012Sejakowatz 
262252a38012Sejakowatz status_t
262352a38012Sejakowatz BMediaRoster::GetWriteFileFormatsFor(const dormant_node_info & in_node,
262452a38012Sejakowatz 									 media_file_format * out_write_formats,
262552a38012Sejakowatz 									 int32 in_write_count,
262652a38012Sejakowatz 									 int32 * out_write_count)
262752a38012Sejakowatz {
262852a38012Sejakowatz 	UNIMPLEMENTED();
262952a38012Sejakowatz 	return B_ERROR;
263052a38012Sejakowatz }
263152a38012Sejakowatz 
263252a38012Sejakowatz 
263352a38012Sejakowatz status_t
263452a38012Sejakowatz BMediaRoster::GetFormatFor(const media_output & output,
263552a38012Sejakowatz 						   media_format * io_format,
263652a38012Sejakowatz 						   uint32 flags)
263752a38012Sejakowatz {
26389bedd42cSbeveloper 	CALLED();
26399bedd42cSbeveloper 	if (io_format == NULL)
26409bedd42cSbeveloper 		return B_BAD_VALUE;
26419bedd42cSbeveloper 	if ((output.node.kind & B_BUFFER_PRODUCER) == 0)
26429bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
26439bedd42cSbeveloper 	if (IS_INVALID_SOURCE(output.source))
26449bedd42cSbeveloper 		return B_MEDIA_BAD_SOURCE;
26459bedd42cSbeveloper 
26469bedd42cSbeveloper 	producer_format_suggestion_requested_request request;
26479bedd42cSbeveloper 	producer_format_suggestion_requested_reply reply;
26489bedd42cSbeveloper 	status_t rv;
26499bedd42cSbeveloper 
26509bedd42cSbeveloper 	request.type = B_MEDIA_UNKNOWN_TYPE;
26519bedd42cSbeveloper 	request.quality = 0; // XXX what should this be?
26529bedd42cSbeveloper 
26539bedd42cSbeveloper 	rv = QueryPort(output.source.port, PRODUCER_FORMAT_SUGGESTION_REQUESTED, &request, sizeof(request), &reply, sizeof(reply));
26549bedd42cSbeveloper 	if (rv != B_OK)
26559bedd42cSbeveloper 		return rv;
26569bedd42cSbeveloper 
26579bedd42cSbeveloper 	*io_format = reply.format;
26589bedd42cSbeveloper 	return B_OK;
265952a38012Sejakowatz }
266052a38012Sejakowatz 
266152a38012Sejakowatz 
266252a38012Sejakowatz status_t
266352a38012Sejakowatz BMediaRoster::GetFormatFor(const media_input & input,
266452a38012Sejakowatz 						   media_format * io_format,
266552a38012Sejakowatz 						   uint32 flags)
266652a38012Sejakowatz {
26679bedd42cSbeveloper 	CALLED();
26689bedd42cSbeveloper 	if (io_format == NULL)
26699bedd42cSbeveloper 		return B_BAD_VALUE;
26709bedd42cSbeveloper 	if ((input.node.kind & B_BUFFER_CONSUMER) == 0)
26719bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
26729bedd42cSbeveloper 	if (IS_INVALID_DESTINATION(input.destination))
26739bedd42cSbeveloper 		return B_MEDIA_BAD_DESTINATION;
26749bedd42cSbeveloper 
26759bedd42cSbeveloper 	consumer_accept_format_request request;
26769bedd42cSbeveloper 	consumer_accept_format_reply reply;
26779bedd42cSbeveloper 	status_t rv;
26789bedd42cSbeveloper 
26799bedd42cSbeveloper 	request.dest = input.destination;
26809bedd42cSbeveloper 	memset(&request.format, 0, sizeof(request.format)); // wildcard
26819bedd42cSbeveloper 
26829bedd42cSbeveloper 	rv = QueryPort(input.destination.port, CONSUMER_ACCEPT_FORMAT, &request, sizeof(request), &reply, sizeof(reply));
26839bedd42cSbeveloper 	if (rv != B_OK)
26849bedd42cSbeveloper 		return rv;
26859bedd42cSbeveloper 
26869bedd42cSbeveloper 	*io_format = reply.format;
26879bedd42cSbeveloper 	return B_OK;
268852a38012Sejakowatz }
268952a38012Sejakowatz 
269052a38012Sejakowatz 
269152a38012Sejakowatz status_t
269252a38012Sejakowatz BMediaRoster::GetFormatFor(const media_node & node,
269352a38012Sejakowatz 						   media_format * io_format,
269452a38012Sejakowatz 						   float quality)
269552a38012Sejakowatz {
269652a38012Sejakowatz 	UNIMPLEMENTED();
26979bedd42cSbeveloper 	if (io_format == NULL)
26989bedd42cSbeveloper 		return B_BAD_VALUE;
26999bedd42cSbeveloper 	if (IS_INVALID_NODE(node))
27009bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
27019bedd42cSbeveloper 	if ((node.kind & (B_BUFFER_CONSUMER | B_BUFFER_PRODUCER)) == 0)
27029bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
27039bedd42cSbeveloper 
27049bedd42cSbeveloper 
270552a38012Sejakowatz 	return B_ERROR;
270652a38012Sejakowatz }
270752a38012Sejakowatz 
270852a38012Sejakowatz 
270952a38012Sejakowatz ssize_t
271052a38012Sejakowatz BMediaRoster::GetNodeAttributesFor(const media_node & node,
271152a38012Sejakowatz 								   media_node_attribute * outArray,
271252a38012Sejakowatz 								   size_t inMaxCount)
271352a38012Sejakowatz {
271452a38012Sejakowatz 	UNIMPLEMENTED();
271552a38012Sejakowatz 	return B_ERROR;
271652a38012Sejakowatz }
271752a38012Sejakowatz 
271852a38012Sejakowatz 
271952a38012Sejakowatz media_node_id
272052a38012Sejakowatz BMediaRoster::NodeIDFor(port_id source_or_destination_port)
272152a38012Sejakowatz {
27229e9417d2Sbeveloper 	CALLED();
27239e9417d2Sbeveloper 
27249e9417d2Sbeveloper 	server_node_id_for_request request;
27259e9417d2Sbeveloper 	server_node_id_for_reply reply;
27269e9417d2Sbeveloper 	status_t rv;
27279e9417d2Sbeveloper 
27289e9417d2Sbeveloper 	request.port = source_or_destination_port;
27299e9417d2Sbeveloper 
27309e9417d2Sbeveloper 	rv = QueryServer(SERVER_NODE_ID_FOR, &request, sizeof(request), &reply, sizeof(reply));
27319e9417d2Sbeveloper 	if (rv != B_OK) {
27325ac4fbd7Sbeveloper 		ERROR("BMediaRoster::NodeIDFor: failed (error %#lx)\n", rv);
27339e9417d2Sbeveloper 		return -1;
27349e9417d2Sbeveloper 	}
27359e9417d2Sbeveloper 
27369e9417d2Sbeveloper 	return reply.nodeid;
273752a38012Sejakowatz }
273852a38012Sejakowatz 
273952a38012Sejakowatz 
274052a38012Sejakowatz status_t
274152a38012Sejakowatz BMediaRoster::GetInstancesFor(media_addon_id addon,
274252a38012Sejakowatz 							  int32 flavor,
274352a38012Sejakowatz 							  media_node_id * out_id,
274452a38012Sejakowatz 							  int32 * io_count)
274552a38012Sejakowatz {
274685dfab2bSbeveloper 	CALLED();
27478b9700adSJérôme Duval 	if (out_id == NULL)
274885dfab2bSbeveloper 		return B_BAD_VALUE;
27498b9700adSJérôme Duval 	if (io_count && *io_count <= 0)
275085dfab2bSbeveloper 		return B_BAD_VALUE;
275185dfab2bSbeveloper 
275285dfab2bSbeveloper 	server_get_instances_for_request request;
275385dfab2bSbeveloper 	server_get_instances_for_reply reply;
275485dfab2bSbeveloper 	status_t rv;
275585dfab2bSbeveloper 
27568b9700adSJérôme Duval 	request.maxcount = (io_count ? *io_count : 1);
275785dfab2bSbeveloper 	request.addon_id = addon;
275885dfab2bSbeveloper 	request.addon_flavor_id = flavor;
275985dfab2bSbeveloper 
276085dfab2bSbeveloper 	rv = QueryServer(SERVER_GET_INSTANCES_FOR, &request, sizeof(request), &reply, sizeof(reply));
276185dfab2bSbeveloper 	if (rv != B_OK) {
27625ac4fbd7Sbeveloper 		ERROR("BMediaRoster::GetLiveNodes failed\n");
276385dfab2bSbeveloper 		return rv;
276452a38012Sejakowatz 	}
276552a38012Sejakowatz 
27668b9700adSJérôme Duval 	if(io_count)
276785dfab2bSbeveloper 		*io_count = reply.count;
276885dfab2bSbeveloper 	if (reply.count > 0)
276985dfab2bSbeveloper 		memcpy(out_id, reply.node_id, sizeof(media_node_id) * reply.count);
277085dfab2bSbeveloper 
277185dfab2bSbeveloper 	return B_OK;
277285dfab2bSbeveloper }
277352a38012Sejakowatz 
277452a38012Sejakowatz 
277552a38012Sejakowatz status_t
277652a38012Sejakowatz BMediaRoster::SetRealtimeFlags(uint32 in_enabled)
277752a38012Sejakowatz {
277852a38012Sejakowatz 	UNIMPLEMENTED();
277952a38012Sejakowatz 	return B_ERROR;
278052a38012Sejakowatz }
278152a38012Sejakowatz 
278252a38012Sejakowatz 
278352a38012Sejakowatz status_t
278452a38012Sejakowatz BMediaRoster::GetRealtimeFlags(uint32 * out_enabled)
278552a38012Sejakowatz {
278652a38012Sejakowatz 	UNIMPLEMENTED();
278752a38012Sejakowatz 	return B_ERROR;
278852a38012Sejakowatz }
278952a38012Sejakowatz 
279052a38012Sejakowatz 
279152a38012Sejakowatz ssize_t
279252a38012Sejakowatz BMediaRoster::AudioBufferSizeFor(int32 channel_count,
279352a38012Sejakowatz 								 uint32 sample_format,
279452a38012Sejakowatz 								 float frame_rate,
279552a38012Sejakowatz 								 bus_type bus_kind)
279652a38012Sejakowatz {
2797df6c2e83Sbeveloper 	bigtime_t buffer_duration;
2798df6c2e83Sbeveloper 	ssize_t buffer_size;
2799df6c2e83Sbeveloper 
2800df6c2e83Sbeveloper 	system_info info;
2801df6c2e83Sbeveloper 	get_system_info(&info);
2802df6c2e83Sbeveloper 
2803df6c2e83Sbeveloper 	if (info.cpu_clock_speed > 2000000000)
2804df6c2e83Sbeveloper 		buffer_duration = 2500;
2805df6c2e83Sbeveloper 	else if (info.cpu_clock_speed > 1000000000)
2806df6c2e83Sbeveloper 		buffer_duration = 5000;
2807df6c2e83Sbeveloper 	else if (info.cpu_clock_speed > 600000000)
2808df6c2e83Sbeveloper 		buffer_duration = 10000;
2809df6c2e83Sbeveloper 	else if (info.cpu_clock_speed > 200000000)
2810df6c2e83Sbeveloper 		buffer_duration = 20000;
2811df6c2e83Sbeveloper 	else if (info.cpu_clock_speed > 100000000)
2812df6c2e83Sbeveloper 		buffer_duration = 30000;
2813df6c2e83Sbeveloper 	else
2814df6c2e83Sbeveloper 		buffer_duration = 50000;
2815df6c2e83Sbeveloper 
2816df6c2e83Sbeveloper 	if ((bus_kind == B_ISA_BUS || bus_kind == B_PCMCIA_BUS) && buffer_duration < 25000)
2817df6c2e83Sbeveloper 		buffer_duration = 25000;
2818df6c2e83Sbeveloper 
2819df6c2e83Sbeveloper 	buffer_size = (sample_format & 0xf) * channel_count * (ssize_t)((frame_rate * buffer_duration) / 1000000.0);
2820df6c2e83Sbeveloper 
2821df6c2e83Sbeveloper 	printf("Suggested buffer duration %Ld, size %ld\n", buffer_duration, buffer_size);
2822df6c2e83Sbeveloper 
2823df6c2e83Sbeveloper 	return buffer_size;
282452a38012Sejakowatz }
282552a38012Sejakowatz 
282652a38012Sejakowatz 
282752a38012Sejakowatz /* Use MediaFlags to inquire about specific features of the Media Kit. */
282852a38012Sejakowatz /* Returns < 0 for "not present", positive size for output data size. */
282952a38012Sejakowatz /* 0 means that the capability is present, but no data about it. */
283052a38012Sejakowatz /* static */ ssize_t
283152a38012Sejakowatz BMediaRoster::MediaFlags(media_flags cap,
283252a38012Sejakowatz 						 void * buf,
283352a38012Sejakowatz 						 size_t maxSize)
283452a38012Sejakowatz {
283552a38012Sejakowatz 	UNIMPLEMENTED();
283652a38012Sejakowatz 	return 0;
283752a38012Sejakowatz }
283852a38012Sejakowatz 
283952a38012Sejakowatz 
284052a38012Sejakowatz /* BLooper overrides */
284152a38012Sejakowatz /* virtual */ void
284252a38012Sejakowatz BMediaRoster::MessageReceived(BMessage * message)
284352a38012Sejakowatz {
2844cf4e2277Sbeveloper 	switch (message->what) {
2845cf4e2277Sbeveloper 		case 'PING':
2846cf4e2277Sbeveloper 		{
28476396865dSbeveloper 			// media_server plays ping-pong with the BMediaRosters
28486396865dSbeveloper 			// to detect dead teams. Normal communication uses ports.
28496396865dSbeveloper 			static BMessage pong('PONG');
28506396865dSbeveloper 			message->SendReply(&pong, static_cast<BHandler *>(NULL), 2000000);
28516396865dSbeveloper 			return;
28526396865dSbeveloper 		}
28536396865dSbeveloper 
2854cf4e2277Sbeveloper 		case NODE_FINAL_RELEASE:
2855cf4e2277Sbeveloper 		{
2856cf4e2277Sbeveloper 			// this function is called by a BMediaNode to delete
2857cf4e2277Sbeveloper 			// itself, as this needs to be done from another thread
2858cf4e2277Sbeveloper 			// context, it is done here.
2859cf4e2277Sbeveloper 			// XXX If a node is released using BMediaRoster::ReleaseNode()
2860cf4e2277Sbeveloper 			// XXX instead of using BMediaNode::Release() / BMediaNode::Acquire()
2861cf4e2277Sbeveloper 			// XXX fRefCount of the BMediaNode will not be correct.
2862cf4e2277Sbeveloper 
2863cf4e2277Sbeveloper 			BMediaNode *node;
2864cf4e2277Sbeveloper 			message->FindPointer("node", reinterpret_cast<void **>(&node));
2865cf4e2277Sbeveloper 
286654187cc6Sbeveloper 			TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE saving node %ld configuration\n", node->ID());
286754187cc6Sbeveloper 			MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(node);
2868cf4e2277Sbeveloper 
286954187cc6Sbeveloper 			TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE releasing node %ld\n", node->ID());
2870cf4e2277Sbeveloper 			node->DeleteHook(node); // we don't call Release(), see above!
2871cf4e2277Sbeveloper 			return;
2872cf4e2277Sbeveloper 		}
2873cf4e2277Sbeveloper 	}
28746396865dSbeveloper 	printf("BMediaRoster::MessageReceived: unknown message!\n");
28756396865dSbeveloper 	message->PrintToStream();
287652a38012Sejakowatz }
287752a38012Sejakowatz 
287852a38012Sejakowatz /* virtual */ bool
287952a38012Sejakowatz BMediaRoster::QuitRequested()
288052a38012Sejakowatz {
288152a38012Sejakowatz 	UNIMPLEMENTED();
288252a38012Sejakowatz 	return true;
288352a38012Sejakowatz }
288452a38012Sejakowatz 
288552a38012Sejakowatz /* virtual */ BHandler *
288652a38012Sejakowatz BMediaRoster::ResolveSpecifier(BMessage *msg,
288752a38012Sejakowatz 				 int32 index,
288852a38012Sejakowatz 				 BMessage *specifier,
288952a38012Sejakowatz 				 int32 form,
289052a38012Sejakowatz 				 const char *property)
289152a38012Sejakowatz {
289252a38012Sejakowatz 	UNIMPLEMENTED();
289352a38012Sejakowatz 	return 0;
289452a38012Sejakowatz }
289552a38012Sejakowatz 
289652a38012Sejakowatz 
289752a38012Sejakowatz /* virtual */ status_t
289852a38012Sejakowatz BMediaRoster::GetSupportedSuites(BMessage *data)
289952a38012Sejakowatz {
290052a38012Sejakowatz 	UNIMPLEMENTED();
290152a38012Sejakowatz 	return B_ERROR;
290252a38012Sejakowatz }
290352a38012Sejakowatz 
290452a38012Sejakowatz 
290552a38012Sejakowatz BMediaRoster::~BMediaRoster()
290652a38012Sejakowatz {
290752a38012Sejakowatz 	CALLED();
29086396865dSbeveloper 
29096396865dSbeveloper 	// unregister this application with the media server
29106396865dSbeveloper 	server_unregister_app_request request;
29116396865dSbeveloper 	server_unregister_app_reply reply;
29126396865dSbeveloper 	request.team = team;
29136396865dSbeveloper 	QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply, sizeof(reply));
291452a38012Sejakowatz }
291552a38012Sejakowatz 
291652a38012Sejakowatz 
291752a38012Sejakowatz /*************************************************************
291852a38012Sejakowatz  * private BMediaRoster
291952a38012Sejakowatz  *************************************************************/
292052a38012Sejakowatz 
292152a38012Sejakowatz // deprecated call
292252a38012Sejakowatz status_t
292352a38012Sejakowatz BMediaRoster::SetOutputBuffersFor(const media_source & output,
292452a38012Sejakowatz 								  BBufferGroup * group,
292552a38012Sejakowatz 								  bool will_reclaim )
292652a38012Sejakowatz {
292752a38012Sejakowatz 	UNIMPLEMENTED();
29289e9417d2Sbeveloper 	debugger("BMediaRoster::SetOutputBuffersFor missing\n");
292952a38012Sejakowatz 	return B_ERROR;
293052a38012Sejakowatz }
293152a38012Sejakowatz 
293252a38012Sejakowatz 
293352a38012Sejakowatz /* FBC stuffing (Mmmh, Stuffing!) */
293452a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_0(void *) { return B_ERROR; }
293552a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_1(void *) { return B_ERROR; }
293652a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_2(void *) { return B_ERROR; }
293752a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_3(void *) { return B_ERROR; }
293852a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_4(void *) { return B_ERROR; }
293952a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_5(void *) { return B_ERROR; }
294052a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_6(void *) { return B_ERROR; }
294152a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_7(void *) { return B_ERROR; }
294252a38012Sejakowatz 
294352a38012Sejakowatz 
294452a38012Sejakowatz BMediaRoster::BMediaRoster() :
29456396865dSbeveloper 	BLooper("_BMediaRoster_", B_URGENT_DISPLAY_PRIORITY, B_LOOPER_PORT_DEFAULT_CAPACITY)
294652a38012Sejakowatz {
294752a38012Sejakowatz 	CALLED();
29486396865dSbeveloper 
29496396865dSbeveloper 	// start the looper
29506396865dSbeveloper 	Run();
295152a38012Sejakowatz }
295252a38012Sejakowatz 
29536396865dSbeveloper 
295452a38012Sejakowatz /* static */ status_t
295552a38012Sejakowatz BMediaRoster::ParseCommand(BMessage & reply)
295652a38012Sejakowatz {
295752a38012Sejakowatz 	UNIMPLEMENTED();
295852a38012Sejakowatz 	return B_ERROR;
295952a38012Sejakowatz }
296052a38012Sejakowatz 
296152a38012Sejakowatz 
296252a38012Sejakowatz status_t
296352a38012Sejakowatz BMediaRoster::GetDefaultInfo(media_node_id for_default,
296452a38012Sejakowatz 							 BMessage & out_config)
296552a38012Sejakowatz {
296652a38012Sejakowatz 	UNIMPLEMENTED();
296752a38012Sejakowatz 	return B_ERROR;
296852a38012Sejakowatz }
296952a38012Sejakowatz 
297052a38012Sejakowatz 
297152a38012Sejakowatz 
297252a38012Sejakowatz status_t
297352a38012Sejakowatz BMediaRoster::SetRunningDefault(media_node_id for_default,
297452a38012Sejakowatz 								const media_node & node)
297552a38012Sejakowatz {
297652a38012Sejakowatz 	UNIMPLEMENTED();
297752a38012Sejakowatz 	return B_ERROR;
297852a38012Sejakowatz }
297952a38012Sejakowatz 
298052a38012Sejakowatz 
298152a38012Sejakowatz /*************************************************************
298252a38012Sejakowatz  * static BMediaRoster variables
298352a38012Sejakowatz  *************************************************************/
298452a38012Sejakowatz 
298552a38012Sejakowatz bool BMediaRoster::_isMediaServer;
298652a38012Sejakowatz port_id BMediaRoster::_mReplyPort;
298752a38012Sejakowatz int32 BMediaRoster::_mReplyPortRes;
298852a38012Sejakowatz int32 BMediaRoster::_mReplyPortUnavailCount;
298952a38012Sejakowatz BMediaRoster * BMediaRoster::_sDefault = NULL;
299052a38012Sejakowatz 
2991