xref: /haiku/src/kits/media/MediaRoster.cpp (revision df612ac9b3f05f1f2ddfd5dfd4891f956759e3db)
1255a01c7Sbeveloper /*
234c72144SAxel Dörfler  * Copyright 2008 Maurice Kalinowski, haiku@kaldience.com
3332cc6bcSAxel Dörfler  * Copyright 2009-2012, Axel Dörfler, axeld@pinc-software.de.
434c72144SAxel Dörfler  *
534c72144SAxel Dörfler  * All rights reserved. Distributed under the terms of the MIT License.
634c72144SAxel Dörfler  */
734c72144SAxel Dörfler 
834c72144SAxel Dörfler /*
965b73ae4SMarcus Overhagen  * Copyright (c) 2002-2006 Marcus Overhagen <Marcus@Overhagen.de>
10255a01c7Sbeveloper  *
11255a01c7Sbeveloper  * Permission is hereby granted, free of charge, to any person obtaining
12255a01c7Sbeveloper  * a copy of this software and associated documentation files or portions
13255a01c7Sbeveloper  * thereof (the "Software"), to deal in the Software without restriction,
14255a01c7Sbeveloper  * including without limitation the rights to use, copy, modify, merge,
15255a01c7Sbeveloper  * publish, distribute, sublicense, and/or sell copies of the Software,
16255a01c7Sbeveloper  * and to permit persons to whom the Software is furnished to do so, subject
17255a01c7Sbeveloper  * to the following conditions:
18255a01c7Sbeveloper  *
19255a01c7Sbeveloper  *  * Redistributions of source code must retain the above copyright notice,
20255a01c7Sbeveloper  *    this list of conditions and the following disclaimer.
21255a01c7Sbeveloper  *
22255a01c7Sbeveloper  *  * Redistributions in binary form must reproduce the above copyright notice
23255a01c7Sbeveloper  *    in the  binary, as well as this list of conditions and the following
24255a01c7Sbeveloper  *    disclaimer in the documentation and/or other materials provided with
25255a01c7Sbeveloper  *    the distribution.
26255a01c7Sbeveloper  *
27255a01c7Sbeveloper  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28255a01c7Sbeveloper  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29255a01c7Sbeveloper  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30255a01c7Sbeveloper  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31255a01c7Sbeveloper  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32255a01c7Sbeveloper  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33255a01c7Sbeveloper  * THE SOFTWARE.
34255a01c7Sbeveloper  */
356938364bSMaurice Kalinowski 
36255a01c7Sbeveloper 
37255a01c7Sbeveloper /* to comply with the license above, do not remove the following line */
388b940bb4SStephan Aßmus char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "
398b940bb4SStephan Aßmus 	"Overhagen <Marcus@Overhagen.de>";
40255a01c7Sbeveloper 
419dec2310SAxel Dörfler 
4252a38012Sejakowatz #include <MediaRoster.h>
438b940bb4SStephan Aßmus 
44a715f908SStephan Aßmus #include <new>
45a715f908SStephan Aßmus 
466938364bSMaurice Kalinowski #include <BufferConsumer.h>
476938364bSMaurice Kalinowski #include <BufferProducer.h>
4852a38012Sejakowatz #include <Locker.h>
4952a38012Sejakowatz #include <Message.h>
5052a38012Sejakowatz #include <Messenger.h>
516938364bSMaurice Kalinowski #include <MimeType.h>
5252a38012Sejakowatz #include <OS.h>
536938364bSMaurice Kalinowski #include <ParameterWeb.h>
546938364bSMaurice Kalinowski #include <StopWatch.h>
5552a38012Sejakowatz #include <String.h>
5652a38012Sejakowatz #include <TimeSource.h>
578b940bb4SStephan Aßmus 
589dec2310SAxel Dörfler #include <AppMisc.h>
599dec2310SAxel Dörfler 
602f9ed888SAxel Dörfler #include <debug.h>
612f9ed888SAxel Dörfler #include <DataExchange.h>
622f9ed888SAxel Dörfler #include <DormantNodeManager.h>
632f9ed888SAxel Dörfler #include <MediaRosterEx.h>
642f9ed888SAxel Dörfler #include <MediaMisc.h>
652f9ed888SAxel Dörfler #include <Notifications.h>
662f9ed888SAxel Dörfler #include <ServerInterface.h>
672f9ed888SAxel Dörfler #include <SharedBufferList.h>
682f9ed888SAxel Dörfler 
69835140c8Sbeveloper #include "TimeSourceObjectManager.h"
7052a38012Sejakowatz 
712f9ed888SAxel Dörfler 
72f0a1eb2dSAxel Dörfler namespace BPrivate {
73f0a1eb2dSAxel Dörfler namespace media {
7452a38012Sejakowatz 
75f0a1eb2dSAxel Dörfler 
76f0a1eb2dSAxel Dörfler class MediaInitializer {
7752a38012Sejakowatz public:
78f0a1eb2dSAxel Dörfler 	MediaInitializer()
796396865dSbeveloper 	{
80f0a1eb2dSAxel Dörfler 		InitDataExchange();
81f0a1eb2dSAxel Dörfler 	}
82f0a1eb2dSAxel Dörfler 
83f0a1eb2dSAxel Dörfler 	~MediaInitializer()
84f0a1eb2dSAxel Dörfler 	{
85f0a1eb2dSAxel Dörfler 		if (BMediaRoster::CurrentRoster() != NULL) {
86f0a1eb2dSAxel Dörfler 			BMediaRoster::CurrentRoster()->Lock();
87f0a1eb2dSAxel Dörfler 			BMediaRoster::CurrentRoster()->Quit();
886396865dSbeveloper 		}
896396865dSbeveloper 	}
908b04ffc1Sbeveloper };
9152a38012Sejakowatz 
92f0a1eb2dSAxel Dörfler 
939dec2310SAxel Dörfler }	// namespace media
949dec2310SAxel Dörfler }	// namespace BPrivate
959dec2310SAxel Dörfler 
968b04ffc1Sbeveloper using namespace BPrivate::media;
9752a38012Sejakowatz 
989dec2310SAxel Dörfler 
99f0a1eb2dSAxel Dörfler static MediaInitializer sInitializer;
10052a38012Sejakowatz 
1019dec2310SAxel Dörfler 
10234c72144SAxel Dörfler BMediaRosterEx::BMediaRosterEx(status_t* _error)
1039dec2310SAxel Dörfler 	:
1049dec2310SAxel Dörfler 	BMediaRoster()
105dcfb6bfcSJérôme Duval {
106f0a1eb2dSAxel Dörfler 	InitDataExchange();
107f0a1eb2dSAxel Dörfler 
108f0a1eb2dSAxel Dörfler 	gDormantNodeManager = new DormantNodeManager;
109f0a1eb2dSAxel Dörfler 	gTimeSourceObjectManager = new TimeSourceObjectManager;
110f0a1eb2dSAxel Dörfler 
111dcfb6bfcSJérôme Duval 	// register this application with the media server
112dcfb6bfcSJérôme Duval 	server_register_app_request request;
113dcfb6bfcSJérôme Duval 	server_register_app_reply reply;
1149dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
115dcfb6bfcSJérôme Duval 	request.messenger = BMessenger(NULL, this);
1169dec2310SAxel Dörfler 
1179dec2310SAxel Dörfler 	status_t status = QueryServer(SERVER_REGISTER_APP, &request,
1189dec2310SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
1199dec2310SAxel Dörfler 	if (status != B_OK)
12034c72144SAxel Dörfler 		*_error = B_MEDIA_SYSTEM_FAILURE;
121a7fb4c16SMaurice Kalinowski 	else
12234c72144SAxel Dörfler 		*_error = B_OK;
123dcfb6bfcSJérôme Duval }
124dcfb6bfcSJérôme Duval 
12534c72144SAxel Dörfler 
1263620737cSbeveloper status_t
12754187cc6Sbeveloper BMediaRosterEx::SaveNodeConfiguration(BMediaNode* node)
12854187cc6Sbeveloper {
1299dec2310SAxel Dörfler 	int32 flavorID;
1309dec2310SAxel Dörfler 	BMediaAddOn* addon = node->AddOn(&flavorID);
1319dec2310SAxel Dörfler 	if (addon == NULL) {
1328056f0dbSStephan Aßmus 		// NOTE: This node could have been created by an application,
1338056f0dbSStephan Aßmus 		// it does not mean there is an error.
13434c72144SAxel Dörfler 		// TODO: this check incorrectly triggers on BeOS R5 BT848 node
135332cc6bcSAxel Dörfler 		TRACE("BMediaRosterEx::SaveNodeConfiguration node %" B_PRId32 " not "
136332cc6bcSAxel Dörfler 			"instantiated from BMediaAddOn!\n", node->ID());
13754187cc6Sbeveloper 		return B_ERROR;
13854187cc6Sbeveloper 	}
1399dec2310SAxel Dörfler 
1409dec2310SAxel Dörfler 	media_addon_id addonID = addon->AddonID();
14154187cc6Sbeveloper 
14234c72144SAxel Dörfler 	// TODO: fix this
1438056f0dbSStephan Aßmus 	printf("### BMediaRosterEx::SaveNodeConfiguration should save addon-id "
144332cc6bcSAxel Dörfler 		"%" B_PRId32 ", flavor-id %" B_PRId32 " config NOW!\n", addonID,
145332cc6bcSAxel Dörfler 		flavorID);
14654187cc6Sbeveloper 	return B_OK;
14754187cc6Sbeveloper }
14854187cc6Sbeveloper 
14934c72144SAxel Dörfler 
15054187cc6Sbeveloper status_t
1519dec2310SAxel Dörfler BMediaRosterEx::LoadNodeConfiguration(media_addon_id addonID, int32 flavorID,
1529dec2310SAxel Dörfler 	BMessage *_msg)
15354187cc6Sbeveloper {
15434c72144SAxel Dörfler 	// TODO: fix this
1559dec2310SAxel Dörfler 	_msg->MakeEmpty(); // to be fully R5 compliant
1568b940bb4SStephan Aßmus 	printf("### BMediaRosterEx::LoadNodeConfiguration should load addon-id "
157332cc6bcSAxel Dörfler 		"%" B_PRId32 ", flavor-id %" B_PRId32 " config NOW!\n", addonID,
158332cc6bcSAxel Dörfler 		flavorID);
15954187cc6Sbeveloper 	return B_OK;
16054187cc6Sbeveloper }
16154187cc6Sbeveloper 
16234c72144SAxel Dörfler 
16354187cc6Sbeveloper status_t
1649dec2310SAxel Dörfler BMediaRosterEx::IncrementAddonFlavorInstancesCount(media_addon_id addonID,
1659dec2310SAxel Dörfler 	int32 flavorID)
16654187cc6Sbeveloper {
1679c3b4706SAxel Dörfler 	server_change_flavor_instances_count_request request;
1689c3b4706SAxel Dörfler 	server_change_flavor_instances_count_reply reply;
16973794717Sbeveloper 
1709c3b4706SAxel Dörfler 	request.add_on_id = addonID;
1719dec2310SAxel Dörfler 	request.flavor_id = flavorID;
17273794717Sbeveloper 	request.delta = 1;
1739dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
1749c3b4706SAxel Dörfler 	return QueryServer(SERVER_CHANGE_FLAVOR_INSTANCES_COUNT, &request,
17534c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
17654187cc6Sbeveloper }
17754187cc6Sbeveloper 
17834c72144SAxel Dörfler 
17954187cc6Sbeveloper status_t
1809dec2310SAxel Dörfler BMediaRosterEx::DecrementAddonFlavorInstancesCount(media_addon_id addonID,
1819dec2310SAxel Dörfler 	int32 flavorID)
18254187cc6Sbeveloper {
1839c3b4706SAxel Dörfler 	server_change_flavor_instances_count_request request;
1849c3b4706SAxel Dörfler 	server_change_flavor_instances_count_reply reply;
18573794717Sbeveloper 
1869c3b4706SAxel Dörfler 	request.add_on_id = addonID;
1879dec2310SAxel Dörfler 	request.flavor_id = flavorID;
18873794717Sbeveloper 	request.delta = -1;
1899dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
1909c3b4706SAxel Dörfler 	return QueryServer(SERVER_CHANGE_FLAVOR_INSTANCES_COUNT, &request,
19134c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
19254187cc6Sbeveloper }
19354187cc6Sbeveloper 
19434c72144SAxel Dörfler 
19554187cc6Sbeveloper status_t
1966aee58a4SJérôme Duval BMediaRosterEx::ReleaseNodeAll(const media_node& node)
1976aee58a4SJérôme Duval {
1986aee58a4SJérôme Duval 		CALLED();
1996aee58a4SJérôme Duval 	if (IS_INVALID_NODE(node))
2006aee58a4SJérôme Duval 		return B_MEDIA_BAD_NODE;
2016aee58a4SJérôme Duval 
2026aee58a4SJérôme Duval 	if (node.kind & NODE_KIND_NO_REFCOUNTING) {
2036aee58a4SJérôme Duval 		printf("BMediaRoster::ReleaseNodeAll, trying to release reference "
204332cc6bcSAxel Dörfler 			"counting disabled timesource, node %" B_PRId32 ", port %" B_PRId32
205332cc6bcSAxel Dörfler 			", team %" B_PRId32 "\n",
2066aee58a4SJérôme Duval 			node.node, node.port, BPrivate::current_team());
2076aee58a4SJérôme Duval 		return B_OK;
2086aee58a4SJérôme Duval 	}
2096aee58a4SJérôme Duval 
2106aee58a4SJérôme Duval 	server_release_node_request request;
2116aee58a4SJérôme Duval 	server_release_node_reply reply;
2126aee58a4SJérôme Duval 	status_t rv;
2136aee58a4SJérôme Duval 
2146aee58a4SJérôme Duval 	request.node = node;
2156aee58a4SJérôme Duval 	request.team = BPrivate::current_team();
2166aee58a4SJérôme Duval 
217332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::ReleaseNodeAll, node %" B_PRId32 ", port %" B_PRId32
218332cc6bcSAxel Dörfler 		", team %" B_PRId32 "\n",
2196aee58a4SJérôme Duval 		node.node, node.port, BPrivate::current_team());
2206aee58a4SJérôme Duval 
2216aee58a4SJérôme Duval 	rv = QueryServer(SERVER_RELEASE_NODE_ALL, &request, sizeof(request), &reply,
2226aee58a4SJérôme Duval 		sizeof(reply));
2236aee58a4SJérôme Duval 	if (rv != B_OK) {
224c74afb57SJérôme Duval 		ERROR("BMediaRoster::ReleaseNodeAll failed to query media_server, "
225c74afb57SJérôme Duval 			"retrying local, node %" B_PRId32 ", port %"
226c74afb57SJérôme Duval 			B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
227c74afb57SJérôme Duval 			BPrivate::current_team());
228c74afb57SJérôme Duval 		node_final_release_command command;
229c74afb57SJérôme Duval 		rv = SendToPort(node.port, NODE_FINAL_RELEASE, &command,
230c74afb57SJérôme Duval 			sizeof(command));
231c74afb57SJérôme Duval 		if (rv != B_OK) {
232332cc6bcSAxel Dörfler 			ERROR("BMediaRoster::ReleaseNodeAll FAILED, node %" B_PRId32 ", port %"
233332cc6bcSAxel Dörfler 				B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
234332cc6bcSAxel Dörfler 				BPrivate::current_team());
2356aee58a4SJérôme Duval 		}
236c74afb57SJérôme Duval 	}
2376aee58a4SJérôme Duval 	return rv;
2386aee58a4SJérôme Duval }
2396aee58a4SJérôme Duval 
2406aee58a4SJérôme Duval 
2416aee58a4SJérôme Duval status_t
24254187cc6Sbeveloper BMediaRosterEx::SetNodeCreator(media_node_id node, team_id creator)
24354187cc6Sbeveloper {
24454187cc6Sbeveloper 	server_set_node_creator_request request;
24554187cc6Sbeveloper 	server_set_node_creator_reply reply;
24654187cc6Sbeveloper 
24754187cc6Sbeveloper 	request.node = node;
24854187cc6Sbeveloper 	request.creator = creator;
24934c72144SAxel Dörfler 	return QueryServer(SERVER_SET_NODE_CREATOR, &request, sizeof(request),
25034c72144SAxel Dörfler 		&reply, sizeof(reply));
25154187cc6Sbeveloper }
25254187cc6Sbeveloper 
25334c72144SAxel Dörfler 
25454187cc6Sbeveloper status_t
25534c72144SAxel Dörfler BMediaRosterEx::GetNode(node_type type, media_node* out_node,
25634c72144SAxel Dörfler 	int32* out_input_id, BString* out_input_name)
25752a38012Sejakowatz {
25852a38012Sejakowatz 	if (out_node == NULL)
25952a38012Sejakowatz 		return B_BAD_VALUE;
26052a38012Sejakowatz 
2618c6a6096Sbeveloper 	server_get_node_request request;
2628c6a6096Sbeveloper 	server_get_node_reply reply;
26352a38012Sejakowatz 	status_t rv;
26452a38012Sejakowatz 
2658c6a6096Sbeveloper 	request.type = type;
2669dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
26734c72144SAxel Dörfler 	rv = QueryServer(SERVER_GET_NODE, &request, sizeof(request), &reply,
26834c72144SAxel Dörfler 		sizeof(reply));
2698c6a6096Sbeveloper 	if (rv != B_OK)
2708c6a6096Sbeveloper 		return rv;
27152a38012Sejakowatz 
27252a38012Sejakowatz 	*out_node = reply.node;
27352a38012Sejakowatz 	if (out_input_id)
27452a38012Sejakowatz 		*out_input_id = reply.input_id;
27552a38012Sejakowatz 	if (out_input_name)
27652a38012Sejakowatz 		*out_input_name = reply.input_name;
2778c6a6096Sbeveloper 	return rv;
27852a38012Sejakowatz }
27952a38012Sejakowatz 
28034c72144SAxel Dörfler 
2813620737cSbeveloper status_t
28234c72144SAxel Dörfler BMediaRosterEx::SetNode(node_type type, const media_node* node,
28334c72144SAxel Dörfler 	const dormant_node_info* info, const media_input* input)
28452a38012Sejakowatz {
2858c6a6096Sbeveloper 	server_set_node_request request;
2868c6a6096Sbeveloper 	server_set_node_reply reply;
28752a38012Sejakowatz 
2888c6a6096Sbeveloper 	request.type = type;
28934c72144SAxel Dörfler 	request.use_node = node != NULL;
29034c72144SAxel Dörfler 	if (node != NULL)
2918c6a6096Sbeveloper 		request.node = *node;
29234c72144SAxel Dörfler 	request.use_dni = info != NULL;
29334c72144SAxel Dörfler 	if (info != NULL)
2948c6a6096Sbeveloper 		request.dni = *info;
29534c72144SAxel Dörfler 	request.use_input = input != NULL;
29634c72144SAxel Dörfler 	if (input != NULL)
2978c6a6096Sbeveloper 		request.input = *input;
29852a38012Sejakowatz 
29934c72144SAxel Dörfler 	return QueryServer(SERVER_SET_NODE, &request, sizeof(request), &reply,
30034c72144SAxel Dörfler 		sizeof(reply));
30152a38012Sejakowatz }
30252a38012Sejakowatz 
30334c72144SAxel Dörfler 
3043620737cSbeveloper status_t
3058b04ffc1Sbeveloper BMediaRosterEx::GetAllOutputs(const media_node& node, List<media_output>* list)
3063620737cSbeveloper {
3073620737cSbeveloper 	int32 cookie;
3083620737cSbeveloper 	status_t rv;
3093620737cSbeveloper 	status_t result;
3103620737cSbeveloper 
311332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRosterEx::GetAllOutputs() node %" B_PRId32 ", port %"
312332cc6bcSAxel Dörfler 		B_PRId32 "\n", node.node, node.port);
3135ac4fbd7Sbeveloper 
31465b73ae4SMarcus Overhagen 	if (!(node.kind & B_BUFFER_PRODUCER)) {
315332cc6bcSAxel Dörfler 		ERROR("BMediaRosterEx::GetAllOutputs: node %" B_PRId32 " is not a "
31634c72144SAxel Dörfler 			"B_BUFFER_PRODUCER\n", node.node);
31765b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_NODE;
31865b73ae4SMarcus Overhagen 	}
31965b73ae4SMarcus Overhagen 
3203620737cSbeveloper 	result = B_OK;
3213620737cSbeveloper 	cookie = 0;
32276669a29Sbeveloper 	list->MakeEmpty();
3233620737cSbeveloper 	for (;;) {
3243620737cSbeveloper 		producer_get_next_output_request request;
3253620737cSbeveloper 		producer_get_next_output_reply reply;
3263620737cSbeveloper 		request.cookie = cookie;
32734c72144SAxel Dörfler 		rv = QueryPort(node.port, PRODUCER_GET_NEXT_OUTPUT, &request,
32834c72144SAxel Dörfler 			sizeof(request), &reply, sizeof(reply));
3293620737cSbeveloper 		if (rv != B_OK)
3303620737cSbeveloper 			break;
3313620737cSbeveloper 		cookie = reply.cookie;
33276669a29Sbeveloper 		if (!list->Insert(reply.output)) {
3335ac4fbd7Sbeveloper 			ERROR("GetAllOutputs: list->Insert failed\n");
3343620737cSbeveloper 			result = B_ERROR;
3353620737cSbeveloper 		}
3365ac4fbd7Sbeveloper 		#if DEBUG >= 3
337332cc6bcSAxel Dörfler 			PRINT(3," next cookie %" B_PRId32 ", ", cookie);
3385ac4fbd7Sbeveloper 			PRINT_OUTPUT("output ", reply.output);
3395ac4fbd7Sbeveloper 		#endif
3403620737cSbeveloper 	}
3413620737cSbeveloper 
3423620737cSbeveloper 	producer_dispose_output_cookie_request request;
3433620737cSbeveloper 	producer_dispose_output_cookie_reply reply;
34434c72144SAxel Dörfler 	QueryPort(node.port, PRODUCER_DISPOSE_OUTPUT_COOKIE, &request,
34534c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
3463620737cSbeveloper 
3473620737cSbeveloper 	return result;
3483620737cSbeveloper }
3493620737cSbeveloper 
35034c72144SAxel Dörfler 
3513620737cSbeveloper status_t
3524d2d96e0Sbeveloper BMediaRosterEx::GetAllOutputs(BBufferProducer* node, List<media_output>* list)
3534d2d96e0Sbeveloper {
3544d2d96e0Sbeveloper 	int32 cookie;
3554d2d96e0Sbeveloper 	status_t result;
3564d2d96e0Sbeveloper 
357332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRosterEx::GetAllOutputs() (by pointer) node %" B_PRId32
358332cc6bcSAxel Dörfler 		", port %" B_PRId32 "\n", node->ID(), node->ControlPort());
3594d2d96e0Sbeveloper 
3604d2d96e0Sbeveloper 	result = B_OK;
3614d2d96e0Sbeveloper 	cookie = 0;
3624d2d96e0Sbeveloper 	list->MakeEmpty();
3634d2d96e0Sbeveloper 	for (;;) {
3644d2d96e0Sbeveloper 		media_output output;
3654d2d96e0Sbeveloper 		if (B_OK != node->GetNextOutput(&cookie, &output))
3664d2d96e0Sbeveloper 			break;
3674d2d96e0Sbeveloper 		if (!list->Insert(output)) {
3684d2d96e0Sbeveloper 			ERROR("GetAllOutputs: list->Insert failed\n");
3694d2d96e0Sbeveloper 			result = B_ERROR;
3704d2d96e0Sbeveloper 		}
3714d2d96e0Sbeveloper 		#if DEBUG >= 3
372332cc6bcSAxel Dörfler 			PRINT(3," next cookie %" B_PRId32 ", ", cookie);
3734d2d96e0Sbeveloper 			PRINT_OUTPUT("output ", output);
3744d2d96e0Sbeveloper 		#endif
3754d2d96e0Sbeveloper 	}
3764d2d96e0Sbeveloper 	node->DisposeOutputCookie(cookie);
3774d2d96e0Sbeveloper 	return result;
3784d2d96e0Sbeveloper }
3794d2d96e0Sbeveloper 
38034c72144SAxel Dörfler 
3814d2d96e0Sbeveloper status_t
3828b04ffc1Sbeveloper BMediaRosterEx::GetAllInputs(const media_node& node, List<media_input>* list)
3833620737cSbeveloper {
3843620737cSbeveloper 	int32 cookie;
3853620737cSbeveloper 	status_t rv;
3863620737cSbeveloper 	status_t result;
3873620737cSbeveloper 
388332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRosterEx::GetAllInputs() node %" B_PRId32 ", port %"
389332cc6bcSAxel Dörfler 		B_PRId32 "\n", node.node, node.port);
3905ac4fbd7Sbeveloper 
39165b73ae4SMarcus Overhagen 	if (!(node.kind & B_BUFFER_CONSUMER)) {
392332cc6bcSAxel Dörfler 		ERROR("BMediaRosterEx::GetAllInputs: node %" B_PRId32 " is not a "
39334c72144SAxel Dörfler 			"B_BUFFER_CONSUMER\n", node.node);
39465b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_NODE;
39565b73ae4SMarcus Overhagen 	}
39665b73ae4SMarcus Overhagen 
3973620737cSbeveloper 	result = B_OK;
3983620737cSbeveloper 	cookie = 0;
39976669a29Sbeveloper 	list->MakeEmpty();
4003620737cSbeveloper 	for (;;) {
4013620737cSbeveloper 		consumer_get_next_input_request request;
4023620737cSbeveloper 		consumer_get_next_input_reply reply;
4033620737cSbeveloper 		request.cookie = cookie;
40434c72144SAxel Dörfler 		rv = QueryPort(node.port, CONSUMER_GET_NEXT_INPUT, &request,
40534c72144SAxel Dörfler 			sizeof(request), &reply, sizeof(reply));
4063620737cSbeveloper 		if (rv != B_OK)
4073620737cSbeveloper 			break;
4083620737cSbeveloper 		cookie = reply.cookie;
40976669a29Sbeveloper 		if (!list->Insert(reply.input)) {
4105ac4fbd7Sbeveloper 			ERROR("GetAllInputs: list->Insert failed\n");
4113620737cSbeveloper 			result = B_ERROR;
4123620737cSbeveloper 		}
4135ac4fbd7Sbeveloper 		#if DEBUG >= 3
414332cc6bcSAxel Dörfler 			PRINT(3," next cookie %" B_PRId32 ", ", cookie);
4155ac4fbd7Sbeveloper 			PRINT_OUTPUT("input ", reply.input);
4165ac4fbd7Sbeveloper 		#endif
4173620737cSbeveloper 	}
4183620737cSbeveloper 
4193620737cSbeveloper 	consumer_dispose_input_cookie_request request;
4203620737cSbeveloper 	consumer_dispose_input_cookie_reply reply;
42134c72144SAxel Dörfler 	QueryPort(node.port, CONSUMER_DISPOSE_INPUT_COOKIE, &request,
42234c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
4233620737cSbeveloper 
4243620737cSbeveloper 	return result;
4253620737cSbeveloper }
4263620737cSbeveloper 
42734c72144SAxel Dörfler 
4283620737cSbeveloper status_t
4294d2d96e0Sbeveloper BMediaRosterEx::GetAllInputs(BBufferConsumer* node, List<media_input>* list)
4304d2d96e0Sbeveloper {
4314d2d96e0Sbeveloper 	int32 cookie;
4324d2d96e0Sbeveloper 	status_t result;
4334d2d96e0Sbeveloper 
434332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRosterEx::GetAllInputs() (by pointer) node %" B_PRId32
435332cc6bcSAxel Dörfler 		", port %" B_PRId32 "\n", node->ID(), node->ControlPort());
4364d2d96e0Sbeveloper 
4374d2d96e0Sbeveloper 	result = B_OK;
4384d2d96e0Sbeveloper 	cookie = 0;
4394d2d96e0Sbeveloper 	list->MakeEmpty();
4404d2d96e0Sbeveloper 	for (;;) {
4414d2d96e0Sbeveloper 		media_input input;
4424d2d96e0Sbeveloper 		if (B_OK != node->GetNextInput(&cookie, &input))
4434d2d96e0Sbeveloper 			break;
4444d2d96e0Sbeveloper 		if (!list->Insert(input)) {
4454d2d96e0Sbeveloper 			ERROR("GetAllInputs: list->Insert failed\n");
4464d2d96e0Sbeveloper 			result = B_ERROR;
4474d2d96e0Sbeveloper 		}
4484d2d96e0Sbeveloper 		#if DEBUG >= 3
449332cc6bcSAxel Dörfler 			PRINT(3," next cookie %" B_PRId32 ", ", cookie);
4504d2d96e0Sbeveloper 			PRINT_INPUT("input ", input);
4514d2d96e0Sbeveloper 		#endif
4524d2d96e0Sbeveloper 	}
4534d2d96e0Sbeveloper 	node->DisposeInputCookie(cookie);
4544d2d96e0Sbeveloper 	return result;
4554d2d96e0Sbeveloper }
4564d2d96e0Sbeveloper 
45734c72144SAxel Dörfler 
4584d2d96e0Sbeveloper status_t
4598b04ffc1Sbeveloper BMediaRosterEx::PublishOutputs(const media_node& node, List<media_output>* list)
4603620737cSbeveloper {
4613620737cSbeveloper 	server_publish_outputs_request request;
4623620737cSbeveloper 	server_publish_outputs_reply reply;
4633620737cSbeveloper 	media_output* output;
4643620737cSbeveloper 	media_output* outputs;
4653620737cSbeveloper 	int32 count;
466a7b41a96Sbeveloper 	status_t rv;
4673620737cSbeveloper 
46876669a29Sbeveloper 	count = list->CountItems();
469332cc6bcSAxel Dörfler 	TRACE("PublishOutputs: publishing %" B_PRId32 "\n", count);
4703620737cSbeveloper 
4713620737cSbeveloper 	request.node = node;
4723620737cSbeveloper 	request.count = count;
4733620737cSbeveloper 	if (count > MAX_OUTPUTS) {
4743620737cSbeveloper 		void *start_addr;
4753620737cSbeveloper 		size_t size;
47640f36b03Sbeveloper 		size = ROUND_UP_TO_PAGE(count * sizeof(media_output));
47734c72144SAxel Dörfler 		request.area = create_area("publish outputs", &start_addr,
47834c72144SAxel Dörfler 			B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
4793620737cSbeveloper 		if (request.area < B_OK) {
480332cc6bcSAxel Dörfler 			ERROR("PublishOutputs: failed to create area, %#" B_PRIx32 "\n",
48134c72144SAxel Dörfler 				request.area);
4823620737cSbeveloper 			return (status_t)request.area;
4833620737cSbeveloper 		}
4843620737cSbeveloper 		outputs = static_cast<media_output *>(start_addr);
4853620737cSbeveloper 	} else {
4863620737cSbeveloper 		request.area = -1;
4873620737cSbeveloper 		outputs = request.outputs;
4883620737cSbeveloper 	}
489332cc6bcSAxel Dörfler 	TRACE("PublishOutputs: area %" B_PRId32 "\n", request.area);
4903620737cSbeveloper 
49176669a29Sbeveloper 	int i;
49276669a29Sbeveloper 	for (i = 0, list->Rewind(); list->GetNext(&output); i++) {
49376669a29Sbeveloper 		ASSERT(i < count);
4943620737cSbeveloper 		outputs[i] = *output;
4953620737cSbeveloper 	}
4963620737cSbeveloper 
49734c72144SAxel Dörfler 	rv = QueryServer(SERVER_PUBLISH_OUTPUTS, &request, sizeof(request),
49834c72144SAxel Dörfler 		&reply, sizeof(reply));
499a7b41a96Sbeveloper 
500a7b41a96Sbeveloper 	if (request.area != -1)
501a7b41a96Sbeveloper 		delete_area(request.area);
502a7b41a96Sbeveloper 
503a7b41a96Sbeveloper 	return rv;
5043620737cSbeveloper }
5053620737cSbeveloper 
50634c72144SAxel Dörfler 
5073620737cSbeveloper status_t
5088b04ffc1Sbeveloper BMediaRosterEx::PublishInputs(const media_node& node, List<media_input>* list)
5093620737cSbeveloper {
5103620737cSbeveloper 	server_publish_inputs_request request;
5113620737cSbeveloper 	server_publish_inputs_reply reply;
5123620737cSbeveloper 	media_input* input;
5133620737cSbeveloper 	media_input* inputs;
5143620737cSbeveloper 	int32 count;
515a7b41a96Sbeveloper 	status_t rv;
5163620737cSbeveloper 
51776669a29Sbeveloper 	count = list->CountItems();
518332cc6bcSAxel Dörfler 	TRACE("PublishInputs: publishing %" B_PRId32 "\n", count);
5193620737cSbeveloper 
5203620737cSbeveloper 	request.node = node;
5213620737cSbeveloper 	request.count = count;
5223620737cSbeveloper 	if (count > MAX_INPUTS) {
5233620737cSbeveloper 		void* start_addr;
5243620737cSbeveloper 		size_t size;
52540f36b03Sbeveloper 		size = ROUND_UP_TO_PAGE(count * sizeof(media_input));
52634c72144SAxel Dörfler 		request.area = create_area("publish inputs", &start_addr,
52734c72144SAxel Dörfler 			B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
5283620737cSbeveloper 		if (request.area < B_OK) {
529332cc6bcSAxel Dörfler 			ERROR("PublishInputs: failed to create area, %#" B_PRIx32 "\n",
530332cc6bcSAxel Dörfler 				request.area);
5313620737cSbeveloper 			return (status_t)request.area;
5323620737cSbeveloper 		}
5333620737cSbeveloper 		inputs = static_cast<media_input *>(start_addr);
5343620737cSbeveloper 	} else {
5353620737cSbeveloper 		request.area = -1;
5363620737cSbeveloper 		inputs = request.inputs;
5373620737cSbeveloper 	}
538332cc6bcSAxel Dörfler 	TRACE("PublishInputs: area %" B_PRId32 "\n", request.area);
5393620737cSbeveloper 
54076669a29Sbeveloper 	int i;
54176669a29Sbeveloper 	for (i = 0, list->Rewind(); list->GetNext(&input); i++) {
54276669a29Sbeveloper 		ASSERT(i < count);
5433620737cSbeveloper 		inputs[i] = *input;
5443620737cSbeveloper 	}
5453620737cSbeveloper 
54634c72144SAxel Dörfler 	rv = QueryServer(SERVER_PUBLISH_INPUTS, &request, sizeof(request),
54734c72144SAxel Dörfler 		&reply, sizeof(reply));
548a7b41a96Sbeveloper 
549a7b41a96Sbeveloper 	if (request.area != -1)
550a7b41a96Sbeveloper 		delete_area(request.area);
551a7b41a96Sbeveloper 
552a7b41a96Sbeveloper 	return rv;
5533620737cSbeveloper }
5543620737cSbeveloper 
55534c72144SAxel Dörfler 
55634c72144SAxel Dörfler BTimeSource*
557f4ec236cSAxel Dörfler BMediaRosterEx::MakeTimeSourceObject(media_node_id timeSourceID)
55834c72144SAxel Dörfler {
55934c72144SAxel Dörfler 	media_node clone;
560f4ec236cSAxel Dörfler 	status_t status = GetNodeFor(timeSourceID, &clone);
561f4ec236cSAxel Dörfler 	if (status != B_OK) {
562f4ec236cSAxel Dörfler 		ERROR("BMediaRosterEx::MakeTimeSourceObject: GetNodeFor failed: %s\n",
563f4ec236cSAxel Dörfler 			strerror(status));
56434c72144SAxel Dörfler 		return NULL;
56534c72144SAxel Dörfler 	}
56634c72144SAxel Dörfler 
567f4ec236cSAxel Dörfler 	BTimeSource* source = gTimeSourceObjectManager->GetTimeSource(clone);
56834c72144SAxel Dörfler 	if (source == NULL) {
56934c72144SAxel Dörfler 		ERROR("BMediaRosterEx::MakeTimeSourceObject: GetTimeSource failed\n");
57034c72144SAxel Dörfler 		return NULL;
57134c72144SAxel Dörfler 	}
57234c72144SAxel Dörfler 
57334c72144SAxel Dörfler 	// TODO: release?
57434c72144SAxel Dörfler 	ReleaseNode(clone);
57534c72144SAxel Dörfler 
57634c72144SAxel Dörfler 	return source;
57734c72144SAxel Dörfler }
57834c72144SAxel Dörfler 
57934c72144SAxel Dörfler 
58034c72144SAxel Dörfler //	#pragma mark - public BMediaRoster
58134c72144SAxel Dörfler 
58252a38012Sejakowatz 
58352a38012Sejakowatz status_t
58434c72144SAxel Dörfler BMediaRoster::GetVideoInput(media_node* _node)
58552a38012Sejakowatz {
58652a38012Sejakowatz 	CALLED();
58734c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(VIDEO_INPUT, _node);
58852a38012Sejakowatz }
58952a38012Sejakowatz 
59052a38012Sejakowatz 
59152a38012Sejakowatz status_t
59234c72144SAxel Dörfler BMediaRoster::GetAudioInput(media_node* _node)
59352a38012Sejakowatz {
59452a38012Sejakowatz 	CALLED();
59534c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(AUDIO_INPUT, _node);
59652a38012Sejakowatz }
59752a38012Sejakowatz 
59852a38012Sejakowatz 
59952a38012Sejakowatz status_t
60034c72144SAxel Dörfler BMediaRoster::GetVideoOutput(media_node* _node)
60152a38012Sejakowatz {
60252a38012Sejakowatz 	CALLED();
60334c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(VIDEO_OUTPUT, _node);
60452a38012Sejakowatz }
60552a38012Sejakowatz 
60652a38012Sejakowatz 
60752a38012Sejakowatz status_t
60834c72144SAxel Dörfler BMediaRoster::GetAudioMixer(media_node* _node)
60952a38012Sejakowatz {
61052a38012Sejakowatz 	CALLED();
61134c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(AUDIO_MIXER, _node);
61252a38012Sejakowatz }
61352a38012Sejakowatz 
61452a38012Sejakowatz 
61552a38012Sejakowatz status_t
61634c72144SAxel Dörfler BMediaRoster::GetAudioOutput(media_node* _node)
61752a38012Sejakowatz {
61852a38012Sejakowatz 	CALLED();
61934c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(AUDIO_OUTPUT, _node);
62052a38012Sejakowatz }
62152a38012Sejakowatz 
62252a38012Sejakowatz 
62352a38012Sejakowatz status_t
62434c72144SAxel Dörfler BMediaRoster::GetAudioOutput(media_node* _node, int32* _inputID,
62534c72144SAxel Dörfler 	BString* _inputName)
62652a38012Sejakowatz {
62752a38012Sejakowatz 	CALLED();
62834c72144SAxel Dörfler 	return MediaRosterEx(this)->GetNode(AUDIO_OUTPUT_EX, _node, _inputID,
62934c72144SAxel Dörfler 		_inputName);
63052a38012Sejakowatz }
63152a38012Sejakowatz 
63252a38012Sejakowatz 
63352a38012Sejakowatz status_t
63434c72144SAxel Dörfler BMediaRoster::GetTimeSource(media_node* _node)
63552a38012Sejakowatz {
63652a38012Sejakowatz 	CALLED();
63786bce45bSbeveloper 	status_t rv;
63886bce45bSbeveloper 
63934c72144SAxel Dörfler 	// TODO: need to do this in a nicer way.
64086bce45bSbeveloper 
64134c72144SAxel Dörfler 	rv = MediaRosterEx(this)->GetNode(TIME_SOURCE, _node);
64286bce45bSbeveloper 	if (rv != B_OK)
64386bce45bSbeveloper 		return rv;
64486bce45bSbeveloper 
64586bce45bSbeveloper 	// We don't do reference counting for timesources, that's why we
64686bce45bSbeveloper 	// release the node immediately.
64734c72144SAxel Dörfler 	ReleaseNode(*_node);
64886bce45bSbeveloper 
64986bce45bSbeveloper 	// we need to remember to not use this node with server side reference counting
65034c72144SAxel Dörfler 	_node->kind |= NODE_KIND_NO_REFCOUNTING;
65186bce45bSbeveloper 	return B_OK;
65252a38012Sejakowatz }
65352a38012Sejakowatz 
65452a38012Sejakowatz 
65552a38012Sejakowatz status_t
65652a38012Sejakowatz BMediaRoster::SetVideoInput(const media_node& producer)
65752a38012Sejakowatz {
65852a38012Sejakowatz 	CALLED();
6598b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_INPUT, &producer);
66052a38012Sejakowatz }
66152a38012Sejakowatz 
66252a38012Sejakowatz 
66352a38012Sejakowatz status_t
66452a38012Sejakowatz BMediaRoster::SetVideoInput(const dormant_node_info& producer)
66552a38012Sejakowatz {
66652a38012Sejakowatz 	CALLED();
6678b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_INPUT, NULL, &producer);
66852a38012Sejakowatz }
66952a38012Sejakowatz 
67052a38012Sejakowatz 
67152a38012Sejakowatz status_t
67252a38012Sejakowatz BMediaRoster::SetAudioInput(const media_node& producer)
67352a38012Sejakowatz {
67452a38012Sejakowatz 	CALLED();
6758b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_INPUT, &producer);
67652a38012Sejakowatz }
67752a38012Sejakowatz 
67852a38012Sejakowatz 
67952a38012Sejakowatz status_t
68052a38012Sejakowatz BMediaRoster::SetAudioInput(const dormant_node_info& producer)
68152a38012Sejakowatz {
68252a38012Sejakowatz 	CALLED();
6838b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_INPUT, NULL, &producer);
68452a38012Sejakowatz }
68552a38012Sejakowatz 
68652a38012Sejakowatz 
68752a38012Sejakowatz status_t
68852a38012Sejakowatz BMediaRoster::SetVideoOutput(const media_node& consumer)
68952a38012Sejakowatz {
69052a38012Sejakowatz 	CALLED();
6918b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_OUTPUT, &consumer);
69252a38012Sejakowatz }
69352a38012Sejakowatz 
69452a38012Sejakowatz 
69552a38012Sejakowatz status_t
69652a38012Sejakowatz BMediaRoster::SetVideoOutput(const dormant_node_info& consumer)
69752a38012Sejakowatz {
69852a38012Sejakowatz 	CALLED();
6998b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(VIDEO_OUTPUT, NULL, &consumer);
70052a38012Sejakowatz }
70152a38012Sejakowatz 
70252a38012Sejakowatz 
70352a38012Sejakowatz status_t
70452a38012Sejakowatz BMediaRoster::SetAudioOutput(const media_node& consumer)
70552a38012Sejakowatz {
70652a38012Sejakowatz 	CALLED();
7078b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, &consumer);
70852a38012Sejakowatz }
70952a38012Sejakowatz 
71052a38012Sejakowatz 
71152a38012Sejakowatz status_t
71234c72144SAxel Dörfler BMediaRoster::SetAudioOutput(const media_input& input)
71352a38012Sejakowatz {
71452a38012Sejakowatz 	CALLED();
71534c72144SAxel Dörfler 	return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, NULL, NULL, &input);
71652a38012Sejakowatz }
71752a38012Sejakowatz 
71852a38012Sejakowatz 
71952a38012Sejakowatz status_t
72052a38012Sejakowatz BMediaRoster::SetAudioOutput(const dormant_node_info& consumer)
72152a38012Sejakowatz {
72252a38012Sejakowatz 	CALLED();
7238b04ffc1Sbeveloper 	return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, NULL, &consumer);
72452a38012Sejakowatz }
72552a38012Sejakowatz 
72652a38012Sejakowatz 
72752a38012Sejakowatz status_t
72834c72144SAxel Dörfler BMediaRoster::GetNodeFor(media_node_id node, media_node* clone)
72952a38012Sejakowatz {
7309e9417d2Sbeveloper 	CALLED();
7319e9417d2Sbeveloper 	if (clone == NULL)
7329e9417d2Sbeveloper 		return B_BAD_VALUE;
73365b73ae4SMarcus Overhagen 	if (IS_INVALID_NODEID(node))
7349e9417d2Sbeveloper 		return B_MEDIA_BAD_NODE;
7359e9417d2Sbeveloper 
7369e9417d2Sbeveloper 	server_get_node_for_request request;
7379e9417d2Sbeveloper 	server_get_node_for_reply reply;
7389e9417d2Sbeveloper 	status_t rv;
7399e9417d2Sbeveloper 
7409dec2310SAxel Dörfler 	request.node_id = node;
7419dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
7429e9417d2Sbeveloper 
74334c72144SAxel Dörfler 	rv = QueryServer(SERVER_GET_NODE_FOR, &request, sizeof(request), &reply,
74434c72144SAxel Dörfler 		sizeof(reply));
7459e9417d2Sbeveloper 	if (rv != B_OK)
7469e9417d2Sbeveloper 		return rv;
7479e9417d2Sbeveloper 
7489e9417d2Sbeveloper 	*clone = reply.clone;
7499e9417d2Sbeveloper 	return B_OK;
75052a38012Sejakowatz }
75152a38012Sejakowatz 
75252a38012Sejakowatz 
75352a38012Sejakowatz status_t
75452a38012Sejakowatz BMediaRoster::GetSystemTimeSource(media_node* clone)
75552a38012Sejakowatz {
75652a38012Sejakowatz 	CALLED();
75786bce45bSbeveloper 	status_t rv;
75886bce45bSbeveloper 
75934c72144SAxel Dörfler 	// TODO: need to do this in a nicer way.
76086bce45bSbeveloper 
76186bce45bSbeveloper 	rv = MediaRosterEx(this)->GetNode(SYSTEM_TIME_SOURCE, clone);
76286bce45bSbeveloper 	if (rv != B_OK)
76386bce45bSbeveloper 		return rv;
76486bce45bSbeveloper 
76586bce45bSbeveloper 	// We don't do reference counting for timesources, that's why we
76686bce45bSbeveloper 	// release the node immediately.
76786bce45bSbeveloper 	ReleaseNode(*clone);
76886bce45bSbeveloper 
76934c72144SAxel Dörfler 	// we need to remember to not use this node with server side reference
77034c72144SAxel Dörfler 	// counting
77186bce45bSbeveloper 	clone->kind |= NODE_KIND_NO_REFCOUNTING;
77286bce45bSbeveloper 
77386bce45bSbeveloper 	return B_OK;
77452a38012Sejakowatz }
77552a38012Sejakowatz 
77652a38012Sejakowatz 
77752a38012Sejakowatz status_t
77852a38012Sejakowatz BMediaRoster::ReleaseNode(const media_node& node)
77952a38012Sejakowatz {
7809e9417d2Sbeveloper 	CALLED();
78140f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
7829e9417d2Sbeveloper 		return B_MEDIA_BAD_NODE;
78352a38012Sejakowatz 
78486bce45bSbeveloper 	if (node.kind & NODE_KIND_NO_REFCOUNTING) {
78534c72144SAxel Dörfler 		printf("BMediaRoster::ReleaseNode, trying to release reference "
786332cc6bcSAxel Dörfler 			"counting disabled timesource, node %" B_PRId32 ", port %" B_PRId32
787332cc6bcSAxel Dörfler 			", team %" B_PRId32 "\n", node.node, node.port,
788332cc6bcSAxel Dörfler 			BPrivate::current_team());
78986bce45bSbeveloper 		return B_OK;
79086bce45bSbeveloper 	}
79186bce45bSbeveloper 
7929e9417d2Sbeveloper 	server_release_node_request request;
7939e9417d2Sbeveloper 	server_release_node_reply reply;
794cf4e2277Sbeveloper 	status_t rv;
7959e9417d2Sbeveloper 
7969e9417d2Sbeveloper 	request.node = node;
7979dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
7989e9417d2Sbeveloper 
799332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::ReleaseNode, node %" B_PRId32 ", port %" B_PRId32
800332cc6bcSAxel Dörfler 		", team %" B_PRId32 "\n", node.node, node.port,
801332cc6bcSAxel Dörfler 		BPrivate::current_team());
802cf4e2277Sbeveloper 
80334c72144SAxel Dörfler 	rv = QueryServer(SERVER_RELEASE_NODE, &request, sizeof(request), &reply,
80434c72144SAxel Dörfler 		sizeof(reply));
805cf4e2277Sbeveloper 	if (rv != B_OK) {
806332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::ReleaseNode FAILED, node %" B_PRId32 ", port %"
807332cc6bcSAxel Dörfler 			B_PRId32 ", team %" B_PRId32 "!\n", node.node, node.port,
808332cc6bcSAxel Dörfler 			BPrivate::current_team());
809cf4e2277Sbeveloper 	}
810cf4e2277Sbeveloper 	return rv;
8119e9417d2Sbeveloper }
81252a38012Sejakowatz 
81334c72144SAxel Dörfler 
81452a38012Sejakowatz BTimeSource*
81534c72144SAxel Dörfler BMediaRoster::MakeTimeSourceFor(const media_node& forNode)
81652a38012Sejakowatz {
817f180ef79Sbeveloper 	// MakeTimeSourceFor() returns a BTimeSource object
818f180ef79Sbeveloper 	// corresponding to the specified node's time source.
819f180ef79Sbeveloper 
820835140c8Sbeveloper 	CALLED();
821f180ef79Sbeveloper 
82234c72144SAxel Dörfler 	if (IS_SYSTEM_TIMESOURCE(forNode)) {
823f180ef79Sbeveloper 		// special handling for the system time source
82434c72144SAxel Dörfler 		TRACE("BMediaRoster::MakeTimeSourceFor, asked for system time "
82534c72144SAxel Dörfler 			"source\n");
82634c72144SAxel Dörfler 		return MediaRosterEx(this)->MakeTimeSourceObject(
82734c72144SAxel Dörfler 			NODE_SYSTEM_TIMESOURCE_ID);
828f180ef79Sbeveloper 	}
829f180ef79Sbeveloper 
83034c72144SAxel Dörfler 	if (IS_INVALID_NODE(forNode)) {
831332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::MakeTimeSourceFor: for_node invalid, node %"
832332cc6bcSAxel Dörfler 			B_PRId32 ", port %" B_PRId32 ", kinds 0x%" B_PRIx32 "\n",
833332cc6bcSAxel Dörfler 			forNode.node, forNode.port, forNode.kind);
8345917dd5bSbeveloper 		return NULL;
8350e21b167Sbeveloper 	}
8360e21b167Sbeveloper 
837332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::MakeTimeSourceFor: node %" B_PRId32 " enter\n",
838332cc6bcSAxel Dörfler 		forNode.node);
8395917dd5bSbeveloper 
8405917dd5bSbeveloper 	node_get_timesource_request request;
8415917dd5bSbeveloper 	node_get_timesource_reply reply;
8425917dd5bSbeveloper 	BTimeSource *source;
8435917dd5bSbeveloper 	status_t rv;
8445917dd5bSbeveloper 
84592e575c1Sbeveloper 	// ask the node to get it's current timesource id
84634c72144SAxel Dörfler 	rv = QueryPort(forNode.port, NODE_GET_TIMESOURCE, &request,
84734c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
8485917dd5bSbeveloper 	if (rv != B_OK) {
8495ac4fbd7Sbeveloper 		ERROR("BMediaRoster::MakeTimeSourceFor: request failed\n");
8505917dd5bSbeveloper 		return NULL;
8515917dd5bSbeveloper 	}
8525917dd5bSbeveloper 
8535917dd5bSbeveloper 	source = MediaRosterEx(this)->MakeTimeSourceObject(reply.timesource_id);
8545917dd5bSbeveloper 
855332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::MakeTimeSourceFor: node %" B_PRId32 " leave\n",
856332cc6bcSAxel Dörfler 		forNode.node);
857287f7492Sbeveloper 
858835140c8Sbeveloper 	return source;
85952a38012Sejakowatz }
86052a38012Sejakowatz 
86152a38012Sejakowatz 
86252a38012Sejakowatz status_t
86334c72144SAxel Dörfler BMediaRoster::Connect(const media_source& from, const media_destination& to,
86434c72144SAxel Dörfler 	media_format* _format, media_output* _output, media_input* _input)
86552a38012Sejakowatz {
86634c72144SAxel Dörfler 	return BMediaRoster::Connect(from, to, _format, _output, _input, 0);
867eae26d3dSbeveloper }
868eae26d3dSbeveloper 
869eae26d3dSbeveloper 
870eae26d3dSbeveloper status_t
87134c72144SAxel Dörfler BMediaRoster::Connect(const media_source& from, const media_destination& to,
87234c72144SAxel Dörfler 	media_format* io_format, media_output* out_output, media_input* out_input,
87334c72144SAxel Dörfler 	uint32 in_flags, void* _reserved)
874eae26d3dSbeveloper {
87552a38012Sejakowatz 	CALLED();
87652a38012Sejakowatz 	if (io_format == NULL || out_output == NULL || out_input == NULL)
87752a38012Sejakowatz 		return B_BAD_VALUE;
87840f36b03Sbeveloper 	if (IS_INVALID_SOURCE(from)) {
8795ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: media_source invalid\n");
88052a38012Sejakowatz 		return B_MEDIA_BAD_SOURCE;
8819e9417d2Sbeveloper 	}
88240f36b03Sbeveloper 	if (IS_INVALID_DESTINATION(to)) {
8835ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: media_destination invalid\n");
88452a38012Sejakowatz 		return B_MEDIA_BAD_DESTINATION;
8859e9417d2Sbeveloper 	}
88652a38012Sejakowatz 
88752a38012Sejakowatz 	status_t rv;
88865b73ae4SMarcus Overhagen 
88965b73ae4SMarcus Overhagen 	// find the output and input nodes
89034c72144SAxel Dörfler 	// TODO: isn't there a easier way?
89165b73ae4SMarcus Overhagen 	media_node sourcenode;
89265b73ae4SMarcus Overhagen 	media_node destnode;
89365b73ae4SMarcus Overhagen 	rv = GetNodeFor(NodeIDFor(from.port), &sourcenode);
89465b73ae4SMarcus Overhagen 	if (rv != B_OK) {
895332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::Connect: Can't find source node for port %"
896332cc6bcSAxel Dörfler 			B_PRId32 "\n", from.port);
89765b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
89865b73ae4SMarcus Overhagen 	}
89965b73ae4SMarcus Overhagen 	ReleaseNode(sourcenode);
90065b73ae4SMarcus Overhagen 	rv = GetNodeFor(NodeIDFor(to.port), &destnode);
90165b73ae4SMarcus Overhagen 	if (rv != B_OK) {
90234c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: Can't find destination node for port "
903332cc6bcSAxel Dörfler 			"%" B_PRId32 "\n", to.port);
90465b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
90565b73ae4SMarcus Overhagen 	}
90665b73ae4SMarcus Overhagen 	ReleaseNode(destnode);
90765b73ae4SMarcus Overhagen 
90865b73ae4SMarcus Overhagen 	if (!(sourcenode.kind & B_BUFFER_PRODUCER)) {
909332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::Connect: source node %" B_PRId32 " is not a "
91034c72144SAxel Dörfler 			"B_BUFFER_PRODUCER\n", sourcenode.node);
91165b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
91265b73ae4SMarcus Overhagen 	}
91365b73ae4SMarcus Overhagen 	if (!(destnode.kind & B_BUFFER_CONSUMER)) {
914332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::Connect: destination node %" B_PRId32 " is not a "
91534c72144SAxel Dörfler 			"B_BUFFER_CONSUMER\n", destnode.node);
91665b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
91765b73ae4SMarcus Overhagen 	}
91865b73ae4SMarcus Overhagen 
9198c6a6096Sbeveloper 	producer_format_proposal_request request1;
9208c6a6096Sbeveloper 	producer_format_proposal_reply reply1;
92152a38012Sejakowatz 
92234c72144SAxel Dörfler 	PRINT_FORMAT("BMediaRoster::Connect calling "
92334c72144SAxel Dörfler 		"BBufferProducer::FormatProposal with format  ", *io_format);
92469983609Sbeveloper 
92552a38012Sejakowatz 	// BBufferProducer::FormatProposal
9268c6a6096Sbeveloper 	request1.output = from;
9278c6a6096Sbeveloper 	request1.format = *io_format;
92834c72144SAxel Dörfler 	rv = QueryPort(from.port, PRODUCER_FORMAT_PROPOSAL, &request1,
92934c72144SAxel Dörfler 		sizeof(request1), &reply1, sizeof(reply1));
9308c6a6096Sbeveloper 	if (rv != B_OK) {
93134c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: aborted after "
932332cc6bcSAxel Dörfler 			"BBufferProducer::FormatProposal, status = %#" B_PRIx32 "\n",rv);
93352a38012Sejakowatz 		return rv;
93452a38012Sejakowatz 	}
9358c6a6096Sbeveloper 	// reply1.format now contains the format proposed by the producer
9368c6a6096Sbeveloper 
9378c6a6096Sbeveloper 	consumer_accept_format_request request2;
9388c6a6096Sbeveloper 	consumer_accept_format_reply reply2;
9398c6a6096Sbeveloper 
94034c72144SAxel Dörfler 	PRINT_FORMAT("BMediaRoster::Connect calling "
94134c72144SAxel Dörfler 		"BBufferConsumer::AcceptFormat with format    ", reply1.format);
94269983609Sbeveloper 
9438c6a6096Sbeveloper 	// BBufferConsumer::AcceptFormat
9448c6a6096Sbeveloper 	request2.dest = to;
9458c6a6096Sbeveloper 	request2.format = reply1.format;
94634c72144SAxel Dörfler 	rv = QueryPort(to.port, CONSUMER_ACCEPT_FORMAT, &request2,
94734c72144SAxel Dörfler 		sizeof(request2), &reply2, sizeof(reply2));
9488c6a6096Sbeveloper 	if (rv != B_OK) {
94934c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: aborted after "
950332cc6bcSAxel Dörfler 			"BBufferConsumer::AcceptFormat, status = %#" B_PRIx32 "\n",rv);
9518c6a6096Sbeveloper 		return rv;
9528c6a6096Sbeveloper 	}
9538c6a6096Sbeveloper 	// reply2.format now contains the format accepted by the consumer
9548c6a6096Sbeveloper 
9558c6a6096Sbeveloper 	// BBufferProducer::PrepareToConnect
9568c6a6096Sbeveloper 	producer_prepare_to_connect_request request3;
9578c6a6096Sbeveloper 	producer_prepare_to_connect_reply reply3;
9588c6a6096Sbeveloper 
95934c72144SAxel Dörfler 	PRINT_FORMAT("BMediaRoster::Connect calling "
96034c72144SAxel Dörfler 		"BBufferProducer::PrepareToConnect with format", reply2.format);
96169983609Sbeveloper 
9628c6a6096Sbeveloper 	request3.source = from;
9638c6a6096Sbeveloper 	request3.destination = to;
9648c6a6096Sbeveloper 	request3.format = reply2.format;
96534c72144SAxel Dörfler 	strcpy(request3.name, "XXX some default name"); // TODO: fix this
96634c72144SAxel Dörfler 	rv = QueryPort(from.port, PRODUCER_PREPARE_TO_CONNECT, &request3,
96734c72144SAxel Dörfler 		sizeof(request3), &reply3, sizeof(reply3));
9688c6a6096Sbeveloper 	if (rv != B_OK) {
96934c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: aborted after "
970332cc6bcSAxel Dörfler 			"BBufferProducer::PrepareToConnect, status = %#" B_PRIx32 "\n", rv);
9718c6a6096Sbeveloper 		return rv;
9728c6a6096Sbeveloper 	}
9738c6a6096Sbeveloper 	// reply3.format is still our pretty media format
9748c6a6096Sbeveloper 	// reply3.out_source the real source to be used for the connection
97534c72144SAxel Dörfler 	// reply3.name the name BBufferConsumer::Connected will see in the
97634c72144SAxel Dörfler 	// outInput->name argument
9778c6a6096Sbeveloper 
9788c6a6096Sbeveloper 	// BBufferConsumer::Connected
9798c6a6096Sbeveloper 	consumer_connected_request request4;
9808c6a6096Sbeveloper 	consumer_connected_reply reply4;
9818c6a6096Sbeveloper 	status_t con_status;
9828c6a6096Sbeveloper 
98334c72144SAxel Dörfler 	PRINT_FORMAT("BMediaRoster::Connect calling BBufferConsumer::Connected() "
98434c72144SAxel Dörfler 		"with format       ", reply3.format);
98569983609Sbeveloper 
98669983609Sbeveloper 	request4.input.node = destnode;
98769983609Sbeveloper 	request4.input.source = reply3.out_source;
98869983609Sbeveloper 	request4.input.destination = to;
98969983609Sbeveloper 	request4.input.format = reply3.format;
99069983609Sbeveloper 	strcpy(request4.input.name, reply3.name);
99169983609Sbeveloper 
99234c72144SAxel Dörfler 	con_status = QueryPort(to.port, CONSUMER_CONNECTED, &request4,
99334c72144SAxel Dörfler 		sizeof(request4), &reply4, sizeof(reply4));
9948c6a6096Sbeveloper 	if (con_status != B_OK) {
99534c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: aborting after "
996332cc6bcSAxel Dörfler 			"BBufferConsumer::Connected, status = %#" B_PRIx32 "\n",
997332cc6bcSAxel Dörfler 			con_status);
9988c6a6096Sbeveloper 		// we do NOT return here!
9998c6a6096Sbeveloper 	}
100034c72144SAxel Dörfler 	// con_status contains the status code to be supplied to
100134c72144SAxel Dörfler 	// BBufferProducer::Connect's status argument
100234c72144SAxel Dörfler 	// reply4.input contains the media_input that describes the connection
100334c72144SAxel Dörfler 	// from the consumer point of view
10048c6a6096Sbeveloper 
10058c6a6096Sbeveloper 	// BBufferProducer::Connect
10068c6a6096Sbeveloper 	producer_connect_request request5;
10078c6a6096Sbeveloper 	producer_connect_reply reply5;
10088c6a6096Sbeveloper 
100934c72144SAxel Dörfler 	PRINT_FORMAT("BMediaRoster::Connect calling BBufferProducer::Connect with "
101034c72144SAxel Dörfler 		"format         ", reply4.input.format);
101169983609Sbeveloper 
10128c6a6096Sbeveloper 	request5.error = con_status;
10138c6a6096Sbeveloper 	request5.source = reply3.out_source;
10148c6a6096Sbeveloper 	request5.destination = reply4.input.destination;
101569983609Sbeveloper 	request5.format = reply4.input.format;
10168c6a6096Sbeveloper 	strcpy(request5.name, reply4.input.name);
101734c72144SAxel Dörfler 	rv = QueryPort(reply4.input.source.port, PRODUCER_CONNECT, &request5,
101834c72144SAxel Dörfler 		sizeof(request5), &reply5, sizeof(reply5));
10198c6a6096Sbeveloper 	if (con_status != B_OK) {
10205ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Connect: aborted\n");
10218c6a6096Sbeveloper 		return con_status;
10228c6a6096Sbeveloper 	}
10238c6a6096Sbeveloper 	if (rv != B_OK) {
102434c72144SAxel Dörfler 		ERROR("BMediaRoster::Connect: aborted after BBufferProducer::Connect()"
1025332cc6bcSAxel Dörfler 			", status = %#" B_PRIx32 "\n", rv);
10268c6a6096Sbeveloper 		return rv;
10278c6a6096Sbeveloper 	}
10288c6a6096Sbeveloper 	// reply5.name contains the name assigned to the connection by the producer
10298c6a6096Sbeveloper 
10308c6a6096Sbeveloper 	// initilize connection info
103169983609Sbeveloper 	*io_format = reply4.input.format;
10328c6a6096Sbeveloper 	*out_input = reply4.input;
10338c6a6096Sbeveloper 	out_output->node = sourcenode;
10348c6a6096Sbeveloper 	out_output->source = reply4.input.source;
10358c6a6096Sbeveloper 	out_output->destination = reply4.input.destination;
10368c6a6096Sbeveloper 	out_output->format = reply4.input.format;
10378c6a6096Sbeveloper 	strcpy(out_output->name, reply5.name);
10388c6a6096Sbeveloper 
10398c6a6096Sbeveloper 	// the connection is now made
104069983609Sbeveloper 	printf("BMediaRoster::Connect connection established!\n");
104169983609Sbeveloper 	PRINT_FORMAT("   format", *io_format);
104269983609Sbeveloper 	PRINT_INPUT("   input", *out_input);
104369983609Sbeveloper 	PRINT_OUTPUT("   output", *out_output);
10448c6a6096Sbeveloper 
104534c72144SAxel Dörfler 	// TODO: register connection with server
104634c72144SAxel Dörfler 	// TODO: we should just send a notification, instead of republishing all
104734c72144SAxel Dörfler 	// endpoints
104876669a29Sbeveloper 	List<media_output> outlist;
104976669a29Sbeveloper 	List<media_input> inlist;
105034c72144SAxel Dörfler 	if (MediaRosterEx(this)->GetAllOutputs(out_output->node , &outlist) == B_OK)
10518b04ffc1Sbeveloper 		MediaRosterEx(this)->PublishOutputs(out_output->node , &outlist);
105234c72144SAxel Dörfler 	if (MediaRosterEx(this)->GetAllInputs(out_input->node , &inlist) == B_OK)
10538b04ffc1Sbeveloper 		MediaRosterEx(this)->PublishInputs(out_input->node, &inlist);
10548c6a6096Sbeveloper 
105534c72144SAxel Dörfler 	// TODO: if (mute) BBufferProducer::EnableOutput(false)
10569e9417d2Sbeveloper 	if (in_flags & B_CONNECT_MUTED) {
10579e9417d2Sbeveloper 	}
10588c6a6096Sbeveloper 
10599e9417d2Sbeveloper 	// send a notification
106034c72144SAxel Dörfler 	BPrivate::media::notifications::ConnectionMade(*out_input, *out_output,
106134c72144SAxel Dörfler 		*io_format);
10629e9417d2Sbeveloper 
10638c6a6096Sbeveloper 	return B_OK;
10648c6a6096Sbeveloper };
106552a38012Sejakowatz 
106652a38012Sejakowatz 
106752a38012Sejakowatz status_t
10689e9417d2Sbeveloper BMediaRoster::Disconnect(media_node_id source_nodeid,
106934c72144SAxel Dörfler 	const media_source& source, media_node_id destination_nodeid,
107052a38012Sejakowatz 	const media_destination& destination)
107152a38012Sejakowatz {
10729e9417d2Sbeveloper 	CALLED();
107340f36b03Sbeveloper 	if (IS_INVALID_NODEID(source_nodeid)) {
10745ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: source media_node_id invalid\n");
10759e9417d2Sbeveloper 		return B_MEDIA_BAD_SOURCE;
10769e9417d2Sbeveloper 	}
107740f36b03Sbeveloper 	if (IS_INVALID_NODEID(destination_nodeid)) {
10785ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: destination media_node_id invalid\n");
10799e9417d2Sbeveloper 		return B_MEDIA_BAD_DESTINATION;
10809e9417d2Sbeveloper 	}
108140f36b03Sbeveloper 	if (IS_INVALID_SOURCE(source)) {
10825ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: media_source invalid\n");
10839e9417d2Sbeveloper 		return B_MEDIA_BAD_SOURCE;
10849e9417d2Sbeveloper 	}
108540f36b03Sbeveloper 	if (IS_INVALID_DESTINATION(destination)) {
10865ac4fbd7Sbeveloper 		ERROR("BMediaRoster::Disconnect: media_destination invalid\n");
10879e9417d2Sbeveloper 		return B_MEDIA_BAD_DESTINATION;
10889e9417d2Sbeveloper 	}
10899e9417d2Sbeveloper 
10909e9417d2Sbeveloper 	producer_disconnect_request request2;
10919e9417d2Sbeveloper 	producer_disconnect_reply reply2;
10929e9417d2Sbeveloper 	consumer_disconnected_request request1;
10939e9417d2Sbeveloper 	consumer_disconnected_reply reply1;
10949e9417d2Sbeveloper 	status_t rv1, rv2;
10959e9417d2Sbeveloper 
109634c72144SAxel Dörfler 	// TODO: we should ask the server if this connection really exists
10979e9417d2Sbeveloper 
10989e9417d2Sbeveloper 	request1.source = source;
10999e9417d2Sbeveloper 	request1.destination = destination;
11009e9417d2Sbeveloper 	request2.source = source;
11019e9417d2Sbeveloper 	request2.destination = destination;
11029e9417d2Sbeveloper 
110334c72144SAxel Dörfler 	rv1 = QueryPort(source.port, PRODUCER_DISCONNECT, &request1,
110434c72144SAxel Dörfler 		sizeof(request1), &reply1, sizeof(reply1));
110534c72144SAxel Dörfler 	rv2 = QueryPort(destination.port, CONSUMER_DISCONNECTED, &request2,
110634c72144SAxel Dörfler 		sizeof(request2), &reply2, sizeof(reply2));
11079e9417d2Sbeveloper 
110834c72144SAxel Dörfler 	// TODO: unregister connection with server
110934c72144SAxel Dörfler 	// TODO: we should just send a notification, instead of republishing all
111034c72144SAxel Dörfler 	// endpoints
111176669a29Sbeveloper 	List<media_output> outlist;
111276669a29Sbeveloper 	List<media_input> inlist;
11139e9417d2Sbeveloper 	media_node sourcenode;
11149e9417d2Sbeveloper 	media_node destnode;
111534c72144SAxel Dörfler 	if (GetNodeFor(source_nodeid, &sourcenode) == B_OK) {
111665b73ae4SMarcus Overhagen 		if (!(sourcenode.kind & B_BUFFER_PRODUCER)) {
1117332cc6bcSAxel Dörfler 			ERROR("BMediaRoster::Disconnect: source_nodeid %" B_PRId32
1118332cc6bcSAxel Dörfler 				" is not a B_BUFFER_PRODUCER\n", source_nodeid);
111965b73ae4SMarcus Overhagen 		}
112034c72144SAxel Dörfler 		if (MediaRosterEx(this)->GetAllOutputs(sourcenode , &outlist) == B_OK)
11218b04ffc1Sbeveloper 			MediaRosterEx(this)->PublishOutputs(sourcenode , &outlist);
11229e9417d2Sbeveloper 		ReleaseNode(sourcenode);
11234f09fa2fSbeveloper 	} else {
1124332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::Disconnect: GetNodeFor source_nodeid %" B_PRId32
1125332cc6bcSAxel Dörfler 			" failed\n", source_nodeid);
11264f09fa2fSbeveloper 	}
112734c72144SAxel Dörfler 	if (GetNodeFor(destination_nodeid, &destnode) == B_OK) {
112865b73ae4SMarcus Overhagen 		if (!(destnode.kind & B_BUFFER_CONSUMER)) {
1129332cc6bcSAxel Dörfler 			ERROR("BMediaRoster::Disconnect: destination_nodeid %" B_PRId32
1130332cc6bcSAxel Dörfler 				" is not a B_BUFFER_CONSUMER\n", destination_nodeid);
113165b73ae4SMarcus Overhagen 		}
113234c72144SAxel Dörfler 		if (MediaRosterEx(this)->GetAllInputs(destnode , &inlist) == B_OK)
11338b04ffc1Sbeveloper 			MediaRosterEx(this)->PublishInputs(destnode, &inlist);
11349e9417d2Sbeveloper 		ReleaseNode(destnode);
11354f09fa2fSbeveloper 	} else {
1136332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::Disconnect: GetNodeFor destination_nodeid %"
1137332cc6bcSAxel Dörfler 			B_PRId32 " failed\n", destination_nodeid);
11384f09fa2fSbeveloper 	}
11399e9417d2Sbeveloper 
11409e9417d2Sbeveloper 	// send a notification
11419e9417d2Sbeveloper 	BPrivate::media::notifications::ConnectionBroken(source, destination);
11429e9417d2Sbeveloper 
114334c72144SAxel Dörfler 	return rv1 != B_OK || rv2 != B_OK ? B_ERROR : B_OK;
114452a38012Sejakowatz }
114552a38012Sejakowatz 
114634c72144SAxel Dörfler 
114765b73ae4SMarcus Overhagen status_t
114865b73ae4SMarcus Overhagen BMediaRoster::Disconnect(const media_output& output, const media_input& input)
114965b73ae4SMarcus Overhagen {
115065b73ae4SMarcus Overhagen 	if (IS_INVALID_NODEID(output.node.node)) {
1151332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: output.node.node %" B_PRId32
1152332cc6bcSAxel Dörfler 			" invalid\n", output.node.node);
115365b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
115465b73ae4SMarcus Overhagen 	}
115565b73ae4SMarcus Overhagen 	if (IS_INVALID_NODEID(input.node.node)) {
1156332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.node.node %" B_PRId32
1157332cc6bcSAxel Dörfler 			" invalid\n", input.node.node);
115865b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
115965b73ae4SMarcus Overhagen 	}
116065b73ae4SMarcus Overhagen 	if (!(output.node.kind & B_BUFFER_PRODUCER)) {
1161332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: output.node.kind 0x%" B_PRIx32
1162332cc6bcSAxel Dörfler 			" is no B_BUFFER_PRODUCER\n", output.node.kind);
116365b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
116465b73ae4SMarcus Overhagen 	}
116565b73ae4SMarcus Overhagen 	if (!(input.node.kind & B_BUFFER_CONSUMER)) {
1166332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.node.kind 0x%" B_PRIx32
1167332cc6bcSAxel Dörfler 			" is no B_BUFFER_PRODUCER\n", input.node.kind);
116865b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
116965b73ae4SMarcus Overhagen 	}
117065b73ae4SMarcus Overhagen 	if (input.source.port != output.source.port) {
1171332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.source.port %" B_PRId32
1172332cc6bcSAxel Dörfler 			" doesn't match output.source.port %" B_PRId32 "\n",
1173332cc6bcSAxel Dörfler 			input.source.port, output.source.port);
117465b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
117565b73ae4SMarcus Overhagen 	}
117665b73ae4SMarcus Overhagen 	if (input.source.id != output.source.id) {
1177332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.source.id %" B_PRId32
1178332cc6bcSAxel Dörfler 			" doesn't match output.source.id %" B_PRId32 "\n", input.source.id,
1179332cc6bcSAxel Dörfler 			output.source.id);
118065b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_SOURCE;
118165b73ae4SMarcus Overhagen 	}
118265b73ae4SMarcus Overhagen 	if (input.destination.port != output.destination.port) {
1183332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.destination.port %" B_PRId32
1184332cc6bcSAxel Dörfler 			" doesn't match output.destination.port %" B_PRId32 "\n",
1185332cc6bcSAxel Dörfler 			input.destination.port, output.destination.port);
118665b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
118765b73ae4SMarcus Overhagen 	}
118865b73ae4SMarcus Overhagen 	if (input.destination.id != output.destination.id) {
1189332cc6bcSAxel Dörfler 		printf("BMediaRoster::Disconnect: input.destination.id %" B_PRId32
1190332cc6bcSAxel Dörfler 			" doesn't match output.destination.id %" B_PRId32 "\n",
1191332cc6bcSAxel Dörfler 			input.destination.id, output.destination.id);
119265b73ae4SMarcus Overhagen 		return B_MEDIA_BAD_DESTINATION;
119365b73ae4SMarcus Overhagen 	}
119434c72144SAxel Dörfler 
119534c72144SAxel Dörfler 	return Disconnect(output.node.node, output.source, input.node.node,
119634c72144SAxel Dörfler 		input.destination);
119765b73ae4SMarcus Overhagen }
119865b73ae4SMarcus Overhagen 
119952a38012Sejakowatz 
120052a38012Sejakowatz status_t
120134c72144SAxel Dörfler BMediaRoster::StartNode(const media_node& node, bigtime_t atPerformanceTime)
120252a38012Sejakowatz {
120352a38012Sejakowatz 	CALLED();
12049e9417d2Sbeveloper 	if (node.node <= 0)
120552a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
120652a38012Sejakowatz 
1207332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::StartNode, node %" B_PRId32 ", at perf %" B_PRId64
1208332cc6bcSAxel Dörfler 		"\n", node.node, atPerformanceTime);
12090e21b167Sbeveloper 
12106396865dSbeveloper 	node_start_command command;
121134c72144SAxel Dörfler 	command.performance_time = atPerformanceTime;
121252a38012Sejakowatz 
12136396865dSbeveloper 	return SendToPort(node.port, NODE_START, &command, sizeof(command));
121452a38012Sejakowatz }
121552a38012Sejakowatz 
121652a38012Sejakowatz 
121752a38012Sejakowatz status_t
121834c72144SAxel Dörfler BMediaRoster::StopNode(const media_node& node, bigtime_t atPerformanceTime,
121952a38012Sejakowatz 	bool immediate)
122052a38012Sejakowatz {
122152a38012Sejakowatz 	CALLED();
122240f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
122352a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
122452a38012Sejakowatz 
1225332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::StopNode, node %" B_PRId32 ", at perf %" B_PRId64
1226332cc6bcSAxel Dörfler 		" %s\n", node.node, atPerformanceTime, immediate ? "NOW" : "");
12270e21b167Sbeveloper 
12286396865dSbeveloper 	node_stop_command command;
122934c72144SAxel Dörfler 	command.performance_time = atPerformanceTime;
12306396865dSbeveloper 	command.immediate = immediate;
123152a38012Sejakowatz 
12326396865dSbeveloper 	return SendToPort(node.port, NODE_STOP, &command, sizeof(command));
123352a38012Sejakowatz }
123452a38012Sejakowatz 
123552a38012Sejakowatz 
123652a38012Sejakowatz status_t
123734c72144SAxel Dörfler BMediaRoster::SeekNode(const media_node& node, bigtime_t toMediaTime,
123834c72144SAxel Dörfler 	bigtime_t atPerformanceTime)
123952a38012Sejakowatz {
124052a38012Sejakowatz 	CALLED();
124140f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
124252a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
124352a38012Sejakowatz 
1244332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SeekNode, node %" B_PRId32 ", at perf %" B_PRId64
1245332cc6bcSAxel Dörfler 		", to perf %" B_PRId64 "\n", node.node, atPerformanceTime, toMediaTime);
12460e21b167Sbeveloper 
12476396865dSbeveloper 	node_seek_command command;
124834c72144SAxel Dörfler 	command.media_time = toMediaTime;
124934c72144SAxel Dörfler 	command.performance_time = atPerformanceTime;
125052a38012Sejakowatz 
12516396865dSbeveloper 	return SendToPort(node.port, NODE_SEEK, &command, sizeof(command));
125252a38012Sejakowatz }
125352a38012Sejakowatz 
125452a38012Sejakowatz 
125552a38012Sejakowatz status_t
125634c72144SAxel Dörfler BMediaRoster::StartTimeSource(const media_node& node, bigtime_t atRealTime)
125752a38012Sejakowatz {
125852a38012Sejakowatz 	CALLED();
125960f15390Sbeveloper 	if (IS_SYSTEM_TIMESOURCE(node)) {
126034c72144SAxel Dörfler 		// TODO: debug this
1261332cc6bcSAxel Dörfler 		//ERROR("BMediaRoster::StartTimeSource node %" B_PRId32 " is system timesource\n", node.node);
126260f15390Sbeveloper 		return B_OK;
126360f15390Sbeveloper 	}
126492e575c1Sbeveloper //	if (IS_SHADOW_TIMESOURCE(node)) {
126534c72144SAxel Dörfler //		// TODO: debug this
1266332cc6bcSAxel Dörfler //		ERROR("BMediaRoster::StartTimeSource node %" B_PRId32 " is shadow timesource\n", node.node);
126792e575c1Sbeveloper //		return B_OK;
126892e575c1Sbeveloper //	}
126940f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
1270332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::StartTimeSource node %" B_PRId32 " invalid\n",
127134c72144SAxel Dörfler 			node.node);
127252a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
12730e21b167Sbeveloper 	}
1274332cc6bcSAxel Dörfler 	if ((node.kind & B_TIME_SOURCE) == 0) {
1275332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::StartTimeSource node %" B_PRId32
1276332cc6bcSAxel Dörfler 			" is no timesource\n", node.node);
1277332cc6bcSAxel Dörfler 		return B_MEDIA_BAD_NODE;
1278332cc6bcSAxel Dörfler 	}
12790e21b167Sbeveloper 
1280332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::StartTimeSource, node %" B_PRId32 ", at real %"
1281332cc6bcSAxel Dörfler 		B_PRId64 "\n", node.node, atRealTime);
128252a38012Sejakowatz 
128352a38012Sejakowatz 	BTimeSource::time_source_op_info msg;
128452a38012Sejakowatz 	msg.op = BTimeSource::B_TIMESOURCE_START;
128534c72144SAxel Dörfler 	msg.real_time = atRealTime;
128652a38012Sejakowatz 
128752a38012Sejakowatz 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
128852a38012Sejakowatz }
128952a38012Sejakowatz 
129052a38012Sejakowatz 
129152a38012Sejakowatz status_t
129234c72144SAxel Dörfler BMediaRoster::StopTimeSource(const media_node& node, bigtime_t atRealTime,
129352a38012Sejakowatz 	bool immediate)
129452a38012Sejakowatz {
129552a38012Sejakowatz 	CALLED();
129660f15390Sbeveloper 	if (IS_SYSTEM_TIMESOURCE(node)) {
129734c72144SAxel Dörfler 		// TODO: debug this
12985ac4fbd7Sbeveloper 		//ERROR("BMediaRoster::StopTimeSource node %ld is system timesource\n", node.node);
129960f15390Sbeveloper 		return B_OK;
130060f15390Sbeveloper 	}
130192e575c1Sbeveloper //	if (IS_SHADOW_TIMESOURCE(node)) {
130234c72144SAxel Dörfler //		// TODO: debug this
130392e575c1Sbeveloper //		ERROR("BMediaRoster::StopTimeSource node %ld is shadow timesource\n", node.node);
130492e575c1Sbeveloper //		return B_OK;
130592e575c1Sbeveloper //	}
130640f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
1307332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::StopTimeSource node %" B_PRId32 " invalid\n",
130834c72144SAxel Dörfler 			node.node);
130952a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
13100e21b167Sbeveloper 	}
1311332cc6bcSAxel Dörfler 	if ((node.kind & B_TIME_SOURCE) == 0) {
1312332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::StopTimeSource node %" B_PRId32 " is no "
1313332cc6bcSAxel Dörfler 			"timesource\n", node.node);
1314332cc6bcSAxel Dörfler 		return B_MEDIA_BAD_NODE;
1315332cc6bcSAxel Dörfler 	}
13160e21b167Sbeveloper 
1317332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::StopTimeSource, node %" B_PRId32 ", at real %" B_PRId64
1318332cc6bcSAxel Dörfler 		" %s\n", node.node, atRealTime, immediate ? "NOW" : "");
131952a38012Sejakowatz 
132052a38012Sejakowatz 	BTimeSource::time_source_op_info msg;
132134c72144SAxel Dörfler 	msg.op = immediate ? BTimeSource::B_TIMESOURCE_STOP_IMMEDIATELY
132234c72144SAxel Dörfler 		: BTimeSource::B_TIMESOURCE_STOP;
132334c72144SAxel Dörfler 	msg.real_time = atRealTime;
132452a38012Sejakowatz 
132552a38012Sejakowatz 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
132652a38012Sejakowatz }
132752a38012Sejakowatz 
132852a38012Sejakowatz 
132952a38012Sejakowatz status_t
133052a38012Sejakowatz BMediaRoster::SeekTimeSource(const media_node& node,
133134c72144SAxel Dörfler 	bigtime_t toPerformanceTime, bigtime_t atRealTime)
133252a38012Sejakowatz {
133352a38012Sejakowatz 	CALLED();
133460f15390Sbeveloper 	if (IS_SYSTEM_TIMESOURCE(node)) {
133534c72144SAxel Dörfler 		// TODO: debug this
13365ac4fbd7Sbeveloper 		// ERROR("BMediaRoster::SeekTimeSource node %ld is system timesource\n", node.node);
133760f15390Sbeveloper 		// you can't seek the system time source, but
133860f15390Sbeveloper 		// returning B_ERROR would break StampTV
133960f15390Sbeveloper 		return B_OK;
134060f15390Sbeveloper 	}
134192e575c1Sbeveloper //	if (IS_SHADOW_TIMESOURCE(node)) {
134234c72144SAxel Dörfler //		// TODO: debug this
134392e575c1Sbeveloper //		ERROR("BMediaRoster::SeekTimeSource node %ld is shadow timesource\n", node.node);
134492e575c1Sbeveloper //		return B_OK;
134592e575c1Sbeveloper //	}
134640f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
1347332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::SeekTimeSource node %" B_PRId32 " invalid\n",
134834c72144SAxel Dörfler 			node.node);
134952a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
13500e21b167Sbeveloper 	}
1351332cc6bcSAxel Dörfler 	if ((node.kind & B_TIME_SOURCE) == 0) {
1352332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::SeekTimeSource node %" B_PRId32
1353332cc6bcSAxel Dörfler 			" is no timesource\n", node.node);
1354332cc6bcSAxel Dörfler 		return B_MEDIA_BAD_NODE;
1355332cc6bcSAxel Dörfler 	}
13560e21b167Sbeveloper 
1357332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SeekTimeSource, node %" B_PRId32 ", at real %" B_PRId64
1358332cc6bcSAxel Dörfler 		", to perf %" B_PRId64 "\n", node.node, atRealTime, toPerformanceTime);
135952a38012Sejakowatz 
136052a38012Sejakowatz 	BTimeSource::time_source_op_info msg;
136152a38012Sejakowatz 	msg.op = BTimeSource::B_TIMESOURCE_SEEK;
136234c72144SAxel Dörfler 	msg.real_time = atRealTime;
136334c72144SAxel Dörfler 	msg.performance_time = toPerformanceTime;
136452a38012Sejakowatz 
136552a38012Sejakowatz 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
136652a38012Sejakowatz }
136752a38012Sejakowatz 
136852a38012Sejakowatz 
136952a38012Sejakowatz status_t
137034c72144SAxel Dörfler BMediaRoster::SyncToNode(const media_node& node, bigtime_t atTime,
137152a38012Sejakowatz 	bigtime_t timeout)
137252a38012Sejakowatz {
137352a38012Sejakowatz 	UNIMPLEMENTED();
137460f15390Sbeveloper 	return B_OK;
137552a38012Sejakowatz }
137652a38012Sejakowatz 
137752a38012Sejakowatz 
137852a38012Sejakowatz status_t
137934c72144SAxel Dörfler BMediaRoster::SetRunModeNode(const media_node& node, BMediaNode::run_mode mode)
138052a38012Sejakowatz {
1381332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SetRunModeNode, node %" B_PRId32 ", mode %d\n",
1382332cc6bcSAxel Dörfler 		node.node, mode);
138340f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
138452a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
138552a38012Sejakowatz 
1386dfb2ad61Sbeveloper 	node_set_run_mode_command msg;
138752a38012Sejakowatz 	msg.mode = mode;
138852a38012Sejakowatz 
138952a38012Sejakowatz 	return write_port(node.port, NODE_SET_RUN_MODE, &msg, sizeof(msg));
139052a38012Sejakowatz }
139152a38012Sejakowatz 
139252a38012Sejakowatz 
139352a38012Sejakowatz status_t
139452a38012Sejakowatz BMediaRoster::PrerollNode(const media_node& node)
139552a38012Sejakowatz {
139652a38012Sejakowatz 	CALLED();
139740f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
139852a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
139952a38012Sejakowatz 
140052a38012Sejakowatz 	char dummy;
140152a38012Sejakowatz 	return write_port(node.port, NODE_PREROLL, &dummy, sizeof(dummy));
140252a38012Sejakowatz }
140352a38012Sejakowatz 
140452a38012Sejakowatz 
140552a38012Sejakowatz status_t
140634c72144SAxel Dörfler BMediaRoster::RollNode(const media_node& node, bigtime_t startPerformance,
140734c72144SAxel Dörfler 	bigtime_t stopPerformance, bigtime_t atMediaTime)
140852a38012Sejakowatz {
140952a38012Sejakowatz 	UNIMPLEMENTED();
141052a38012Sejakowatz 	return B_ERROR;
141152a38012Sejakowatz }
141252a38012Sejakowatz 
141352a38012Sejakowatz 
141452a38012Sejakowatz status_t
141552a38012Sejakowatz BMediaRoster::SetProducerRunModeDelay(const media_node& node,
141634c72144SAxel Dörfler 	bigtime_t delay, BMediaNode::run_mode mode)
141752a38012Sejakowatz {
1418332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SetProducerRunModeDelay, node %" B_PRId32 ", delay %"
1419332cc6bcSAxel Dörfler 		B_PRId64 ", mode %d\n", node.node, delay, mode);
142060f15390Sbeveloper 	if (IS_INVALID_NODE(node))
142160f15390Sbeveloper 		return B_MEDIA_BAD_NODE;
142260f15390Sbeveloper 	if ((node.kind & B_BUFFER_PRODUCER) == 0)
142360f15390Sbeveloper 		return B_MEDIA_BAD_NODE;
142460f15390Sbeveloper 
142560f15390Sbeveloper 	producer_set_run_mode_delay_command command;
142660f15390Sbeveloper 	command.mode = mode;
142760f15390Sbeveloper 	command.delay = delay;
142860f15390Sbeveloper 
142934c72144SAxel Dörfler 	return SendToPort(node.port, PRODUCER_SET_RUN_MODE_DELAY, &command,
143034c72144SAxel Dörfler 		sizeof(command));
143152a38012Sejakowatz }
143252a38012Sejakowatz 
143352a38012Sejakowatz 
143452a38012Sejakowatz status_t
143534c72144SAxel Dörfler BMediaRoster::SetProducerRate(const media_node& producer, int32 numer,
143652a38012Sejakowatz 	int32 denom)
143752a38012Sejakowatz {
143852a38012Sejakowatz 	CALLED();
143940f36b03Sbeveloper 	if (IS_INVALID_NODE(producer))
144052a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
144152a38012Sejakowatz 	if ((producer.kind & B_BUFFER_PRODUCER) == 0)
144252a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
144352a38012Sejakowatz 
14446cafce94SAxel Dörfler 	producer_set_play_rate_request request;
14456cafce94SAxel Dörfler 	request.numer = numer;
14466cafce94SAxel Dörfler 	request.denom = denom;
14476cafce94SAxel Dörfler 	status_t status = write_port(producer.node, PRODUCER_SET_PLAY_RATE,
14486cafce94SAxel Dörfler 		&request, sizeof(request));
14496cafce94SAxel Dörfler 	if (status != B_OK)
14506cafce94SAxel Dörfler 		return status;
145152a38012Sejakowatz 
14526cafce94SAxel Dörfler 	producer_set_play_rate_reply reply;
14536cafce94SAxel Dörfler 	int32 code;
14546cafce94SAxel Dörfler 	status = read_port(request.reply_port, &code, &reply, sizeof(reply));
14556cafce94SAxel Dörfler 
14566cafce94SAxel Dörfler 	return status < B_OK ? status : reply.result;
145752a38012Sejakowatz }
145852a38012Sejakowatz 
145952a38012Sejakowatz 
146034c72144SAxel Dörfler /*!	Nodes will have available inputs/outputs as long as they are capable
146134c72144SAxel Dörfler 	of accepting more connections. The node may create an additional
146234c72144SAxel Dörfler 	output or input as the currently available is taken into usage.
146334c72144SAxel Dörfler */
146452a38012Sejakowatz status_t
146552a38012Sejakowatz BMediaRoster::GetLiveNodeInfo(const media_node& node,
146652a38012Sejakowatz 	live_node_info* out_live_info)
146752a38012Sejakowatz {
14689e9417d2Sbeveloper 	CALLED();
14699e9417d2Sbeveloper 	if (out_live_info == NULL)
14709e9417d2Sbeveloper 		return B_BAD_VALUE;
147140f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
14729e9417d2Sbeveloper 		return B_MEDIA_BAD_NODE;
14739e9417d2Sbeveloper 
14749e9417d2Sbeveloper 	server_get_live_node_info_request request;
14759e9417d2Sbeveloper 	server_get_live_node_info_reply reply;
14769e9417d2Sbeveloper 	status_t rv;
14779e9417d2Sbeveloper 
14789e9417d2Sbeveloper 	request.node = node;
14799e9417d2Sbeveloper 
148034c72144SAxel Dörfler 	rv = QueryServer(SERVER_GET_LIVE_NODE_INFO, &request, sizeof(request),
148134c72144SAxel Dörfler 		&reply, sizeof(reply));
14829e9417d2Sbeveloper 	if (rv != B_OK)
14839e9417d2Sbeveloper 		return rv;
14849e9417d2Sbeveloper 
14859e9417d2Sbeveloper 	*out_live_info = reply.live_info;
14869e9417d2Sbeveloper 	return B_OK;
148752a38012Sejakowatz }
148852a38012Sejakowatz 
148952a38012Sejakowatz 
149052a38012Sejakowatz status_t
14919c3b4706SAxel Dörfler BMediaRoster::GetLiveNodes(live_node_info* liveNodes, int32* _totalCount,
149234c72144SAxel Dörfler 	const media_format* hasInput, const media_format* hasOutput,
149334c72144SAxel Dörfler 	const char* name, uint64 nodeKinds)
149452a38012Sejakowatz {
14959e9417d2Sbeveloper 	CALLED();
14969c3b4706SAxel Dörfler 	if (liveNodes == NULL || _totalCount == NULL || *_totalCount <= 0)
14979e9417d2Sbeveloper 		return B_BAD_VALUE;
14989e9417d2Sbeveloper 
149934c72144SAxel Dörfler 	// TODO: we also support the wildcard search as GetDormantNodes does.
150034c72144SAxel Dörfler 	// This needs to be documented
15019e9417d2Sbeveloper 
15029e9417d2Sbeveloper 	server_get_live_nodes_request request;
15039c3b4706SAxel Dörfler 	request.team = BPrivate::current_team();
15049e9417d2Sbeveloper 
15059c3b4706SAxel Dörfler 	request.max_count = *_totalCount;
150634c72144SAxel Dörfler 	request.has_input = hasInput != NULL;
150734c72144SAxel Dörfler 	if (hasInput != NULL) {
150834c72144SAxel Dörfler 		// TODO: we should not make a flat copy of media_format
15099c3b4706SAxel Dörfler 		request.input_format = *hasInput;
151034c72144SAxel Dörfler 	}
151134c72144SAxel Dörfler 	request.has_output = hasOutput != NULL;
151234c72144SAxel Dörfler 	if (hasOutput != NULL) {
151334c72144SAxel Dörfler 		// TODO: we should not make a flat copy of media_format
15149c3b4706SAxel Dörfler 		request.output_format = *hasOutput;
151534c72144SAxel Dörfler 	}
151634c72144SAxel Dörfler 	request.has_name = name != NULL;
15179c3b4706SAxel Dörfler 	if (name != NULL)
15189c3b4706SAxel Dörfler 		strlcpy(request.name, name, sizeof(request.name));
151934c72144SAxel Dörfler 	request.require_kinds = nodeKinds;
15209e9417d2Sbeveloper 
15219c3b4706SAxel Dörfler 	server_get_live_nodes_reply reply;
15229c3b4706SAxel Dörfler 	status_t status = QueryServer(SERVER_GET_LIVE_NODES, &request,
15239c3b4706SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
15249c3b4706SAxel Dörfler 	if (status != B_OK) {
15259c3b4706SAxel Dörfler 		ERROR("BMediaRoster::GetLiveNodes failed querying server: %s\n",
15269c3b4706SAxel Dörfler 			strerror(status));
152734c72144SAxel Dörfler 		*_totalCount = 0;
15289c3b4706SAxel Dörfler 		return status;
15299e9417d2Sbeveloper 	}
15309e9417d2Sbeveloper 
15319c3b4706SAxel Dörfler 	const live_node_info* info;
15329c3b4706SAxel Dörfler 	if (reply.area >= 0)
15339c3b4706SAxel Dörfler 		info = (live_node_info*)reply.address;
15349c3b4706SAxel Dörfler 	else
15359c3b4706SAxel Dörfler 		info = reply.live_info;
15369e9417d2Sbeveloper 
15379c3b4706SAxel Dörfler 	for (int32 i = 0; i < reply.count; i++)
15389c3b4706SAxel Dörfler 		liveNodes[i] = info[i];
15399c3b4706SAxel Dörfler 
15409c3b4706SAxel Dörfler 	if (reply.area >= 0)
15419e9417d2Sbeveloper 		delete_area(reply.area);
154252a38012Sejakowatz 
154334c72144SAxel Dörfler 	*_totalCount = reply.count;
15449e9417d2Sbeveloper 	return B_OK;
15459e9417d2Sbeveloper }
15469e9417d2Sbeveloper 
154752a38012Sejakowatz 
154852a38012Sejakowatz status_t
154952a38012Sejakowatz BMediaRoster::GetFreeInputsFor(const media_node& node,
155034c72144SAxel Dörfler 	media_input * out_free_inputs, int32 buf_num_inputs,
155134c72144SAxel Dörfler 	int32 * out_total_count, media_type filter_type)
155252a38012Sejakowatz {
15533620737cSbeveloper 	CALLED();
15545ac4fbd7Sbeveloper 	if (IS_INVALID_NODE(node)) {
1555332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::GetFreeInputsFor: node %" B_PRId32 ", port %"
1556332cc6bcSAxel Dörfler 			B_PRId32 " invalid\n", node.node, node.port);
15573620737cSbeveloper 		return B_MEDIA_BAD_NODE;
15585ac4fbd7Sbeveloper 	}
15595ac4fbd7Sbeveloper 	if ((node.kind & B_BUFFER_CONSUMER) == 0) {
1560332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::GetFreeInputsFor: node %" B_PRId32 ", port %"
1561332cc6bcSAxel Dörfler 			B_PRId32 " is not a consumer\n", node.node, node.port);
15625ac4fbd7Sbeveloper 		return B_MEDIA_BAD_NODE;
15635ac4fbd7Sbeveloper 	}
15643620737cSbeveloper 	if (out_free_inputs == NULL || out_total_count == NULL)
15653620737cSbeveloper 		return B_BAD_VALUE;
15663620737cSbeveloper 
156776669a29Sbeveloper 	List<media_input> list;
15683620737cSbeveloper 	media_input *input;
15693620737cSbeveloper 	status_t rv;
15703620737cSbeveloper 
15711299bfb2Sbeveloper 	*out_total_count = 0;
15721299bfb2Sbeveloper 
15738b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllInputs(node, &list);
15743620737cSbeveloper 	if (B_OK != rv)
15753620737cSbeveloper 		return rv;
15763620737cSbeveloper 
1577332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetFreeInputsFor node %" B_PRId32 ", max %" B_PRId32
1578332cc6bcSAxel Dörfler 		", filter-type %" B_PRId32 "\n", node.node, buf_num_inputs,
1579332cc6bcSAxel Dörfler 		filter_type);
15805ac4fbd7Sbeveloper 
158176669a29Sbeveloper 	int32 i;
1582b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&input);) {
158334c72144SAxel Dörfler 		if (filter_type != B_MEDIA_UNKNOWN_TYPE
158434c72144SAxel Dörfler 			&& filter_type != input->format.type) {
158534c72144SAxel Dörfler 			// media_type used, but doesn't match
158634c72144SAxel Dörfler 			continue;
158734c72144SAxel Dörfler 		}
158834c72144SAxel Dörfler 		if (input->source != media_source::null) {
158934c72144SAxel Dörfler 			// consumer source already connected
159034c72144SAxel Dörfler 			continue;
159134c72144SAxel Dörfler 		}
159234c72144SAxel Dörfler 
15933620737cSbeveloper 		out_free_inputs[i] = *input;
15943620737cSbeveloper 		*out_total_count += 1;
15953620737cSbeveloper 		buf_num_inputs -= 1;
15965ac4fbd7Sbeveloper 		#if DEBUG >= 3
15975ac4fbd7Sbeveloper 			PRINT_OUTPUT("  input", out_free_inputs[i]);
15985ac4fbd7Sbeveloper 		#endif
15993620737cSbeveloper 		if (buf_num_inputs == 0)
16003620737cSbeveloper 			break;
1601b65a0ac5SJérôme Duval 		i++;
16023620737cSbeveloper 	}
16033620737cSbeveloper 
16048b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishInputs(node, &list);
16053620737cSbeveloper 	return B_OK;
160652a38012Sejakowatz }
160752a38012Sejakowatz 
160852a38012Sejakowatz 
160952a38012Sejakowatz status_t
161052a38012Sejakowatz BMediaRoster::GetConnectedInputsFor(const media_node& node,
161134c72144SAxel Dörfler 	media_input* out_active_inputs, int32 buf_num_inputs,
161252a38012Sejakowatz 	int32* out_total_count)
161352a38012Sejakowatz {
16143620737cSbeveloper 	CALLED();
161540f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_CONSUMER) == 0)
16163620737cSbeveloper 		return B_MEDIA_BAD_NODE;
16173620737cSbeveloper 	if (out_active_inputs == NULL || out_total_count == NULL)
16183620737cSbeveloper 		return B_BAD_VALUE;
16193620737cSbeveloper 
162076669a29Sbeveloper 	List<media_input> list;
16213620737cSbeveloper 	media_input *input;
16223620737cSbeveloper 	status_t rv;
16233620737cSbeveloper 
16241299bfb2Sbeveloper 	*out_total_count = 0;
16251299bfb2Sbeveloper 
16268b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllInputs(node, &list);
16273620737cSbeveloper 	if (B_OK != rv)
16283620737cSbeveloper 		return rv;
16293620737cSbeveloper 
1630332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetConnectedInputsFor node %" B_PRId32 ", max %"
1631332cc6bcSAxel Dörfler 		B_PRId32 "\n", node.node, buf_num_inputs);
16325ac4fbd7Sbeveloper 
163376669a29Sbeveloper 	int32 i;
1634b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&input);) {
16353620737cSbeveloper 		if (input->source == media_source::null)
16363620737cSbeveloper 			continue; // consumer source not connected
16373620737cSbeveloper 		out_active_inputs[i] = *input;
16383620737cSbeveloper 		*out_total_count += 1;
16393620737cSbeveloper 		buf_num_inputs -= 1;
16405ac4fbd7Sbeveloper 		#if DEBUG >= 3
16415ac4fbd7Sbeveloper 			PRINT_OUTPUT("  input ", out_active_inputs[i]);
16425ac4fbd7Sbeveloper 		#endif
16433620737cSbeveloper 		if (buf_num_inputs == 0)
16443620737cSbeveloper 			break;
1645b65a0ac5SJérôme Duval 		i++;
16463620737cSbeveloper 	}
16473620737cSbeveloper 
16488b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishInputs(node, &list);
16493620737cSbeveloper 	return B_OK;
165052a38012Sejakowatz }
165152a38012Sejakowatz 
165252a38012Sejakowatz 
165352a38012Sejakowatz status_t
165434c72144SAxel Dörfler BMediaRoster::GetAllInputsFor(const media_node& node, media_input* out_inputs,
165534c72144SAxel Dörfler 	int32 buf_num_inputs, int32* out_total_count)
165652a38012Sejakowatz {
165752a38012Sejakowatz 	CALLED();
165840f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_CONSUMER) == 0)
165952a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
166052a38012Sejakowatz 	if (out_inputs == NULL || out_total_count == NULL)
166152a38012Sejakowatz 		return B_BAD_VALUE;
166252a38012Sejakowatz 
166376669a29Sbeveloper 	List<media_input> list;
16643620737cSbeveloper 	media_input *input;
166552a38012Sejakowatz 	status_t rv;
166652a38012Sejakowatz 
16671299bfb2Sbeveloper 	*out_total_count = 0;
16681299bfb2Sbeveloper 
16698b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllInputs(node, &list);
16703620737cSbeveloper 	if (B_OK != rv)
16713620737cSbeveloper 		return rv;
16723620737cSbeveloper 
1673332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetAllInputsFor node %" B_PRId32 ", max %" B_PRId32
1674332cc6bcSAxel Dörfler 		"\n", node.node, buf_num_inputs);
16755ac4fbd7Sbeveloper 
167676669a29Sbeveloper 	int32 i;
167776669a29Sbeveloper 	for (i = 0, list.Rewind(); list.GetNext(&input); i++) {
16783620737cSbeveloper 		out_inputs[i] = *input;
167952a38012Sejakowatz 		*out_total_count += 1;
16803620737cSbeveloper 		buf_num_inputs -= 1;
16815ac4fbd7Sbeveloper 		#if DEBUG >= 3
16825ac4fbd7Sbeveloper 			PRINT_OUTPUT("  input ", out_inputs[i]);
16835ac4fbd7Sbeveloper 		#endif
16843620737cSbeveloper 		if (buf_num_inputs == 0)
16853620737cSbeveloper 			break;
168652a38012Sejakowatz 	}
168752a38012Sejakowatz 
16888b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishInputs(node, &list);
16893620737cSbeveloper 	return B_OK;
169052a38012Sejakowatz }
169152a38012Sejakowatz 
169252a38012Sejakowatz 
169352a38012Sejakowatz status_t
169452a38012Sejakowatz BMediaRoster::GetFreeOutputsFor(const media_node& node,
169534c72144SAxel Dörfler 	media_output* out_free_outputs, int32 buf_num_outputs,
169634c72144SAxel Dörfler 	int32* out_total_count, media_type filter_type)
169752a38012Sejakowatz {
16983620737cSbeveloper 	CALLED();
169940f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0)
17003620737cSbeveloper 		return B_MEDIA_BAD_NODE;
17013620737cSbeveloper 	if (out_free_outputs == NULL || out_total_count == NULL)
17023620737cSbeveloper 		return B_BAD_VALUE;
17033620737cSbeveloper 
170476669a29Sbeveloper 	List<media_output> list;
17053620737cSbeveloper 	media_output *output;
17063620737cSbeveloper 	status_t rv;
17073620737cSbeveloper 
17081299bfb2Sbeveloper 	*out_total_count = 0;
17091299bfb2Sbeveloper 
17108b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllOutputs(node, &list);
17113620737cSbeveloper 	if (B_OK != rv)
17123620737cSbeveloper 		return rv;
17133620737cSbeveloper 
1714332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetFreeOutputsFor node %" B_PRId32 ", max %"
1715332cc6bcSAxel Dörfler 		B_PRId32 ", filter-type %" B_PRId32 "\n", node.node, buf_num_outputs,
1716332cc6bcSAxel Dörfler 		filter_type);
17175ac4fbd7Sbeveloper 
171876669a29Sbeveloper 	int32 i;
1719b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&output);) {
172034c72144SAxel Dörfler 		if (filter_type != B_MEDIA_UNKNOWN_TYPE
172134c72144SAxel Dörfler 			&& filter_type != output->format.type) {
172234c72144SAxel Dörfler 			// media_type used, but doesn't match
172334c72144SAxel Dörfler 			continue;
172434c72144SAxel Dörfler 		}
172534c72144SAxel Dörfler 		if (output->destination != media_destination::null) {
172634c72144SAxel Dörfler 			// producer destination already connected
172734c72144SAxel Dörfler 			continue;
172834c72144SAxel Dörfler 		}
172934c72144SAxel Dörfler 
17303620737cSbeveloper 		out_free_outputs[i] = *output;
17313620737cSbeveloper 		*out_total_count += 1;
17323620737cSbeveloper 		buf_num_outputs -= 1;
17335ac4fbd7Sbeveloper 		#if DEBUG >= 3
17345ac4fbd7Sbeveloper 			PRINT_OUTPUT("  output ", out_free_outputs[i]);
17355ac4fbd7Sbeveloper 		#endif
17363620737cSbeveloper 		if (buf_num_outputs == 0)
17373620737cSbeveloper 			break;
1738b65a0ac5SJérôme Duval 		i++;
17393620737cSbeveloper 	}
17403620737cSbeveloper 
17418b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishOutputs(node, &list);
17423620737cSbeveloper 	return B_OK;
174352a38012Sejakowatz }
174452a38012Sejakowatz 
174552a38012Sejakowatz 
174652a38012Sejakowatz status_t
174752a38012Sejakowatz BMediaRoster::GetConnectedOutputsFor(const media_node& node,
174834c72144SAxel Dörfler 	media_output* out_active_outputs, int32 buf_num_outputs,
174952a38012Sejakowatz 	int32* out_total_count)
175052a38012Sejakowatz {
17513620737cSbeveloper 	CALLED();
175240f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0)
17533620737cSbeveloper 		return B_MEDIA_BAD_NODE;
17543620737cSbeveloper 	if (out_active_outputs == NULL || out_total_count == NULL)
17553620737cSbeveloper 		return B_BAD_VALUE;
17563620737cSbeveloper 
175776669a29Sbeveloper 	List<media_output> list;
17583620737cSbeveloper 	media_output *output;
17593620737cSbeveloper 	status_t rv;
17603620737cSbeveloper 
17611299bfb2Sbeveloper 	*out_total_count = 0;
17621299bfb2Sbeveloper 
17638b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllOutputs(node, &list);
17643620737cSbeveloper 	if (B_OK != rv)
17653620737cSbeveloper 		return rv;
17663620737cSbeveloper 
1767332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetConnectedOutputsFor node %" B_PRId32 ", max %"
1768332cc6bcSAxel Dörfler 		B_PRId32 "\n", node.node, buf_num_outputs);
17695ac4fbd7Sbeveloper 
177076669a29Sbeveloper 	int32 i;
1771b65a0ac5SJérôme Duval 	for (i = 0, list.Rewind(); list.GetNext(&output);) {
177234c72144SAxel Dörfler 		if (output->destination == media_destination::null) {
177334c72144SAxel Dörfler 			// producer destination not connected
177434c72144SAxel Dörfler 			continue;
177534c72144SAxel Dörfler 		}
17763620737cSbeveloper 		out_active_outputs[i] = *output;
17773620737cSbeveloper 		*out_total_count += 1;
17783620737cSbeveloper 		buf_num_outputs -= 1;
17795ac4fbd7Sbeveloper 		#if DEBUG >= 3
17805ac4fbd7Sbeveloper 			PRINT_OUTPUT("  output ", out_active_outputs[i]);
17815ac4fbd7Sbeveloper 		#endif
17823620737cSbeveloper 		if (buf_num_outputs == 0)
17833620737cSbeveloper 			break;
1784b65a0ac5SJérôme Duval 		i++;
17853620737cSbeveloper 	}
17863620737cSbeveloper 
17878b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishOutputs(node, &list);
17883620737cSbeveloper 	return B_OK;
178952a38012Sejakowatz }
179052a38012Sejakowatz 
179152a38012Sejakowatz 
179252a38012Sejakowatz status_t
179352a38012Sejakowatz BMediaRoster::GetAllOutputsFor(const media_node& node,
179434c72144SAxel Dörfler 	media_output* out_outputs, int32 buf_num_outputs, int32* out_total_count)
179552a38012Sejakowatz {
179652a38012Sejakowatz 	CALLED();
179740f36b03Sbeveloper 	if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0)
179852a38012Sejakowatz 		return B_MEDIA_BAD_NODE;
179952a38012Sejakowatz 	if (out_outputs == NULL || out_total_count == NULL)
180052a38012Sejakowatz 		return B_BAD_VALUE;
180152a38012Sejakowatz 
180276669a29Sbeveloper 	List<media_output> list;
18033620737cSbeveloper 	media_output *output;
180452a38012Sejakowatz 	status_t rv;
180552a38012Sejakowatz 
18061299bfb2Sbeveloper 	*out_total_count = 0;
18071299bfb2Sbeveloper 
18088b04ffc1Sbeveloper 	rv = MediaRosterEx(this)->GetAllOutputs(node, &list);
18093620737cSbeveloper 	if (B_OK != rv)
18103620737cSbeveloper 		return rv;
18113620737cSbeveloper 
1812332cc6bcSAxel Dörfler 	PRINT(4, "BMediaRoster::GetAllOutputsFor node %" B_PRId32 ", max %" B_PRId32
1813332cc6bcSAxel Dörfler 		"\n", node.node, buf_num_outputs);
18145ac4fbd7Sbeveloper 
181576669a29Sbeveloper 	int32 i;
181676669a29Sbeveloper 	for (i = 0, list.Rewind(); list.GetNext(&output); i++) {
18173620737cSbeveloper 		out_outputs[i] = *output;
181852a38012Sejakowatz 		*out_total_count += 1;
18193620737cSbeveloper 		buf_num_outputs -= 1;
18205ac4fbd7Sbeveloper 		#if DEBUG >= 3
18215ac4fbd7Sbeveloper 			PRINT_OUTPUT("  output ", out_outputs[i]);
18225ac4fbd7Sbeveloper 		#endif
18233620737cSbeveloper 		if (buf_num_outputs == 0)
18243620737cSbeveloper 			break;
182552a38012Sejakowatz 	}
182652a38012Sejakowatz 
18278b04ffc1Sbeveloper 	MediaRosterEx(this)->PublishOutputs(node, &list);
18283620737cSbeveloper 	return B_OK;
182952a38012Sejakowatz }
183052a38012Sejakowatz 
183152a38012Sejakowatz 
183252a38012Sejakowatz status_t
183352a38012Sejakowatz BMediaRoster::StartWatching(const BMessenger& where)
183452a38012Sejakowatz {
1835eae26d3dSbeveloper 	CALLED();
1836eae26d3dSbeveloper 	if (!where.IsValid()) {
18375ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: messenger invalid!\n");
1838eae26d3dSbeveloper 		return B_BAD_VALUE;
1839eae26d3dSbeveloper 	}
184034c72144SAxel Dörfler 	return BPrivate::media::notifications::Register(where, media_node::null,
184134c72144SAxel Dörfler 		B_MEDIA_WILDCARD);
184252a38012Sejakowatz }
184352a38012Sejakowatz 
184452a38012Sejakowatz 
184552a38012Sejakowatz status_t
184634c72144SAxel Dörfler BMediaRoster::StartWatching(const BMessenger & where, int32 notificationType)
184752a38012Sejakowatz {
1848eae26d3dSbeveloper 	CALLED();
1849eae26d3dSbeveloper 	if (!where.IsValid()) {
18505ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: messenger invalid!\n");
1851eae26d3dSbeveloper 		return B_BAD_VALUE;
1852eae26d3dSbeveloper 	}
185334c72144SAxel Dörfler 	if (!BPrivate::media::notifications::IsValidNotificationRequest(false,
185434c72144SAxel Dörfler 			notificationType)) {
18555ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: notificationType invalid!\n");
1856eae26d3dSbeveloper 		return B_BAD_VALUE;
1857eae26d3dSbeveloper 	}
185834c72144SAxel Dörfler 	return BPrivate::media::notifications::Register(where, media_node::null,
185934c72144SAxel Dörfler 		notificationType);
186052a38012Sejakowatz }
186152a38012Sejakowatz 
186252a38012Sejakowatz 
186352a38012Sejakowatz status_t
186434c72144SAxel Dörfler BMediaRoster::StartWatching(const BMessenger& where, const media_node& node,
186552a38012Sejakowatz 	int32 notificationType)
186652a38012Sejakowatz {
1867eae26d3dSbeveloper 	CALLED();
1868eae26d3dSbeveloper 	if (!where.IsValid()) {
18695ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: messenger invalid!\n");
1870eae26d3dSbeveloper 		return B_BAD_VALUE;
1871eae26d3dSbeveloper 	}
187240f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
18735ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: node invalid!\n");
1874eae26d3dSbeveloper 		return B_MEDIA_BAD_NODE;
1875eae26d3dSbeveloper 	}
187634c72144SAxel Dörfler 	if (!BPrivate::media::notifications::IsValidNotificationRequest(true,
187734c72144SAxel Dörfler 			notificationType)) {
18785ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StartWatching: notificationType invalid!\n");
1879eae26d3dSbeveloper 		return B_BAD_VALUE;
1880eae26d3dSbeveloper 	}
188134c72144SAxel Dörfler 	return BPrivate::media::notifications::Register(where, node,
188234c72144SAxel Dörfler 		notificationType);
188352a38012Sejakowatz }
188452a38012Sejakowatz 
188552a38012Sejakowatz 
188652a38012Sejakowatz status_t
188752a38012Sejakowatz BMediaRoster::StopWatching(const BMessenger& where)
188852a38012Sejakowatz {
1889eae26d3dSbeveloper 	CALLED();
1890eae26d3dSbeveloper 	// messenger may already be invalid, so we don't check this
189134c72144SAxel Dörfler 	return BPrivate::media::notifications::Unregister(where, media_node::null,
189234c72144SAxel Dörfler 		B_MEDIA_WILDCARD);
189352a38012Sejakowatz }
189452a38012Sejakowatz 
189552a38012Sejakowatz 
189652a38012Sejakowatz status_t
189734c72144SAxel Dörfler BMediaRoster::StopWatching(const BMessenger& where, int32 notificationType)
189852a38012Sejakowatz {
1899eae26d3dSbeveloper 	CALLED();
1900eae26d3dSbeveloper 	// messenger may already be invalid, so we don't check this
190134c72144SAxel Dörfler 	if (!BPrivate::media::notifications::IsValidNotificationRequest(false,
190234c72144SAxel Dörfler 			notificationType)) {
19035ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopWatching: notificationType invalid!\n");
1904eae26d3dSbeveloper 		return B_BAD_VALUE;
1905eae26d3dSbeveloper 	}
190634c72144SAxel Dörfler 	return BPrivate::media::notifications::Unregister(where, media_node::null,
190734c72144SAxel Dörfler 		notificationType);
190852a38012Sejakowatz }
190952a38012Sejakowatz 
191052a38012Sejakowatz 
191152a38012Sejakowatz status_t
191234c72144SAxel Dörfler BMediaRoster::StopWatching(const BMessenger& where, const media_node& node,
191352a38012Sejakowatz 	int32 notificationType)
191452a38012Sejakowatz {
1915eae26d3dSbeveloper 	CALLED();
1916eae26d3dSbeveloper 	// messenger may already be invalid, so we don't check this
191740f36b03Sbeveloper 	if (IS_INVALID_NODE(node)) {
19185ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopWatching: node invalid!\n");
1919eae26d3dSbeveloper 		return B_MEDIA_BAD_NODE;
1920eae26d3dSbeveloper 	}
192134c72144SAxel Dörfler 	if (!BPrivate::media::notifications::IsValidNotificationRequest(true,
192234c72144SAxel Dörfler 			notificationType)) {
19235ac4fbd7Sbeveloper 		ERROR("BMediaRoster::StopWatching: notificationType invalid!\n");
1924eae26d3dSbeveloper 		return B_BAD_VALUE;
1925eae26d3dSbeveloper 	}
192634c72144SAxel Dörfler 	return BPrivate::media::notifications::Unregister(where, node,
192734c72144SAxel Dörfler 		notificationType);
192852a38012Sejakowatz }
192952a38012Sejakowatz 
193052a38012Sejakowatz 
193152a38012Sejakowatz status_t
193252a38012Sejakowatz BMediaRoster::RegisterNode(BMediaNode* node)
193352a38012Sejakowatz {
193454187cc6Sbeveloper 	CALLED();
193554187cc6Sbeveloper 	// addon-id = -1 (unused), addon-flavor-id = 0 (unused, too)
193654187cc6Sbeveloper 	return MediaRosterEx(this)->RegisterNode(node, -1, 0);
193754187cc6Sbeveloper }
193854187cc6Sbeveloper 
193954187cc6Sbeveloper 
194054187cc6Sbeveloper status_t
19419c3b4706SAxel Dörfler BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addOnID,
19429dec2310SAxel Dörfler 	int32 flavorID)
194354187cc6Sbeveloper {
194452a38012Sejakowatz 	CALLED();
194552a38012Sejakowatz 	if (node == NULL)
194652a38012Sejakowatz 		return B_BAD_VALUE;
194752a38012Sejakowatz 
194854187cc6Sbeveloper 	// some sanity check
194954187cc6Sbeveloper 	// I'm not sure if the media kit warrants to call BMediaNode::AddOn() here.
195054187cc6Sbeveloper 	// Perhaps we don't need it.
19519dec2310SAxel Dörfler 	DEBUG_ONLY(
19529dec2310SAxel Dörfler 		int32 testFlavorID;
19539dec2310SAxel Dörfler 		BMediaAddOn* addon = node->AddOn(&testFlavorID);
19549dec2310SAxel Dörfler 
19556813f2c7SIngo Weinhold 		ASSERT(addOnID == (addon != NULL ? addon->AddonID() : -1));
1956e817f41eSFredrik Modéen //		ASSERT(flavorID == testFlavorID);
19579dec2310SAxel Dörfler 	);
195852a38012Sejakowatz 
19599e9417d2Sbeveloper 	server_register_node_request request;
19609e9417d2Sbeveloper 	server_register_node_reply reply;
19619e9417d2Sbeveloper 
19629c3b4706SAxel Dörfler 	request.add_on_id = addOnID;
19639c3b4706SAxel Dörfler 	request.flavor_id = flavorID;
19649e9417d2Sbeveloper 	strcpy(request.name, node->Name());
19659e9417d2Sbeveloper 	request.kinds = node->Kinds();
19669e9417d2Sbeveloper 	request.port = node->ControlPort();
19679dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
19689e9417d2Sbeveloper 
196934c72144SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: sending SERVER_REGISTER_NODE: port "
1970332cc6bcSAxel Dörfler 		"%" B_PRId32 ", kinds 0x%" B_PRIx64 ", team %" B_PRId32 ", name '%s'\n",
1971332cc6bcSAxel Dörfler 		request.port, request.kinds, request.team, request.name);
19721299bfb2Sbeveloper 
19739c3b4706SAxel Dörfler 	status_t status = QueryServer(SERVER_REGISTER_NODE, &request,
19749c3b4706SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
19759c3b4706SAxel Dörfler 	if (status != B_OK) {
19769c3b4706SAxel Dörfler 		ERROR("BMediaRoster::RegisterNode: failed to register node %s: %s\n",
19779c3b4706SAxel Dörfler 			node->Name(), strerror(status));
19789c3b4706SAxel Dörfler 		return status;
19799e9417d2Sbeveloper 	}
19809e9417d2Sbeveloper 
198134c72144SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: QueryServer SERVER_REGISTER_NODE "
198234c72144SAxel Dörfler 		"finished\n");
19834295907bSbeveloper 
19848b04ffc1Sbeveloper 	// we are a friend class of BMediaNode and initialize this member variable
19859dec2310SAxel Dörfler 	node->fNodeID = reply.node_id;
19869dec2310SAxel Dörfler 	ASSERT(reply.node_id == node->Node().node);
19879dec2310SAxel Dörfler 	ASSERT(reply.node_id == node->ID());
19889e9417d2Sbeveloper 
19899e9417d2Sbeveloper 	// call the callback
19909e9417d2Sbeveloper 	node->NodeRegistered();
19913620737cSbeveloper 
19924295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: NodeRegistered callback finished\n");
19934295907bSbeveloper 
199434c72144SAxel Dörfler 	// if the BMediaNode also inherits from BTimeSource, we need to call
199534c72144SAxel Dörfler 	// BTimeSource::FinishCreate()
19969c3b4706SAxel Dörfler 	if ((node->Kinds() & B_TIME_SOURCE) != 0) {
19979c3b4706SAxel Dörfler 		if (BTimeSource* timeSource = dynamic_cast<BTimeSource*>(node))
19989c3b4706SAxel Dörfler 			timeSource->FinishCreate();
19990e21b167Sbeveloper 	}
20000e21b167Sbeveloper 
20014295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: publishing inputs/outputs\n");
20024295907bSbeveloper 
20033620737cSbeveloper 	// register existing inputs and outputs with the
20043620737cSbeveloper 	// media_server, this allows GetLiveNodes() to work
20053620737cSbeveloper 	// with created, but unconnected nodes.
20064d2d96e0Sbeveloper 	// The node control loop might not be running, or might deadlock
20074d2d96e0Sbeveloper 	// if we send a message and wait for a reply here.
20084d2d96e0Sbeveloper 	// We have a pointer to the node, and thus call the functions directly
20094295907bSbeveloper 
20109c3b4706SAxel Dörfler 	if ((node->Kinds() & B_BUFFER_PRODUCER) != 0) {
20119c3b4706SAxel Dörfler 		if (BBufferProducer* producer = dynamic_cast<BBufferProducer*>(node)) {
2012359ac306Sbeveloper 			List<media_output> list;
20139c3b4706SAxel Dörfler 			if (GetAllOutputs(producer, &list) == B_OK)
2014359ac306Sbeveloper 				PublishOutputs(node->Node(), &list);
201521871f38Sbeveloper 		}
20164d2d96e0Sbeveloper 	}
20179dec2310SAxel Dörfler 	if ((node->Kinds() & B_BUFFER_CONSUMER) != 0) {
20189c3b4706SAxel Dörfler 		if (BBufferConsumer* consumer = dynamic_cast<BBufferConsumer*>(node)) {
2019359ac306Sbeveloper 			List<media_input> list;
20209dec2310SAxel Dörfler 			if (GetAllInputs(consumer, &list) == B_OK)
2021359ac306Sbeveloper 				PublishInputs(node->Node(), &list);
20223620737cSbeveloper 		}
20234d2d96e0Sbeveloper 	}
202421871f38Sbeveloper 
20254295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: sending NodesCreated\n");
20264295907bSbeveloper 
20279dec2310SAxel Dörfler 	BPrivate::media::notifications::NodesCreated(&reply.node_id, 1);
20284295907bSbeveloper 
20294295907bSbeveloper 	TRACE("BMediaRoster::RegisterNode: finished\n");
20304295907bSbeveloper 
2031570f7d04Sbeveloper /*
20329c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: registered node name '%s', id %ld,
20339c3b4706SAxel Dörfler 		addon %ld, flavor %ld\n", node->Name(), node->ID(), addOnID, flavorID);
2034570f7d04Sbeveloper 	TRACE("BMediaRoster::RegisterNode: node this               %p\n", node);
20359c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: node fConsumerThis      %p\n",
20369c3b4706SAxel Dörfler 		node->fConsumerThis);
20379c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: node fProducerThis      %p\n",
20389c3b4706SAxel Dörfler 		node->fProducerThis);
20399c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: node fFileInterfaceThis %p\n",
20409c3b4706SAxel Dörfler 		node->fFileInterfaceThis);
20419c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: node fControllableThis  %p\n",
20429c3b4706SAxel Dörfler 		node->fControllableThis);
20439c3b4706SAxel Dörfler 	TRACE("BMediaRoster::RegisterNode: node fTimeSourceThis    %p\n",
20449c3b4706SAxel Dörfler 		node->fTimeSourceThis);
2045570f7d04Sbeveloper */
20469e9417d2Sbeveloper 	return B_OK;
204752a38012Sejakowatz }
204852a38012Sejakowatz 
204952a38012Sejakowatz 
205052a38012Sejakowatz status_t
205152a38012Sejakowatz BMediaRoster::UnregisterNode(BMediaNode* node)
205252a38012Sejakowatz {
20539e9417d2Sbeveloper 	CALLED();
20549e9417d2Sbeveloper 	if (node == NULL)
20559e9417d2Sbeveloper 		return B_BAD_VALUE;
20569e9417d2Sbeveloper 
205760f15390Sbeveloper 	TRACE("BMediaRoster::UnregisterNode %ld (%p)\n", node->ID(), node);
205860f15390Sbeveloper 
205929bb91d6SAxel Dörfler 	if ((node->fKinds & NODE_KIND_NO_REFCOUNTING) !=0) {
206034c72144SAxel Dörfler 		TRACE("BMediaRoster::UnregisterNode, trying to unregister reference "
206134c72144SAxel Dörfler 			"counting disabled timesource, node %ld, port %ld, team %ld\n",
20629dec2310SAxel Dörfler 			node->ID(), node->ControlPort(), BPrivate::current_team());
206386bce45bSbeveloper 		return B_OK;
206486bce45bSbeveloper 	}
20658b04ffc1Sbeveloper 	if (node->ID() == NODE_UNREGISTERED_ID) {
206634c72144SAxel Dörfler 		PRINT(1, "Warning: BMediaRoster::UnregisterNode: node id %ld, name "
206734c72144SAxel Dörfler 			"'%s' already unregistered\n", node->ID(), node->Name());
20689e9417d2Sbeveloper 		return B_OK;
20699e9417d2Sbeveloper 	}
207054187cc6Sbeveloper 	if (node->fRefCount != 0) {
207134c72144SAxel Dörfler 		PRINT(1, "Warning: BMediaRoster::UnregisterNode: node id %ld, name "
207234c72144SAxel Dörfler 			"'%s' has local reference count of %ld\n", node->ID(), node->Name(),
207334c72144SAxel Dörfler 			node->fRefCount);
207454187cc6Sbeveloper 		// no return here, we continue and unregister!
207554187cc6Sbeveloper 	}
207654187cc6Sbeveloper 
207734c72144SAxel Dörfler 	// Calling BMediaAddOn::GetConfigurationFor(BMediaNode *node,
207834c72144SAxel Dörfler 	// BMessage *config) if this node was instanciated by an add-on needs to
207934c72144SAxel Dörfler 	// be done *somewhere*
208054187cc6Sbeveloper 	// We can't do it here because it is already to late (destructor of the node
208154187cc6Sbeveloper 	// might have been called).
20829e9417d2Sbeveloper 
20839e9417d2Sbeveloper 	server_unregister_node_request request;
20849dec2310SAxel Dörfler 	request.node_id = node->ID();
20859dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
20869e9417d2Sbeveloper 
20871299bfb2Sbeveloper 	// send a notification
20889dec2310SAxel Dörfler 	BPrivate::media::notifications::NodesDeleted(&request.node_id, 1);
20891299bfb2Sbeveloper 
209029bb91d6SAxel Dörfler 	server_unregister_node_reply reply;
2091c74afb57SJérôme Duval 	reply.add_on_id = -1;
209229bb91d6SAxel Dörfler 	status_t status = QueryServer(SERVER_UNREGISTER_NODE, &request,
209329bb91d6SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
209429bb91d6SAxel Dörfler 	if (status != B_OK) {
2095332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::UnregisterNode: failed to unregister node id %"
2096332cc6bcSAxel Dörfler 			B_PRId32 ", name '%s': %s\n", node->ID(), node->Name(),
2097332cc6bcSAxel Dörfler 			strerror(status));
2098c74afb57SJérôme Duval 		BMediaAddOn *addon = node->AddOn(&reply.flavor_id);
2099c74afb57SJérôme Duval 		if (addon != NULL)
2100c74afb57SJérôme Duval 			reply.add_on_id = addon->AddonID();
21019e9417d2Sbeveloper 	}
21029e9417d2Sbeveloper 
21039c3b4706SAxel Dörfler 	if (reply.add_on_id != -1) {
210429bb91d6SAxel Dörfler 		// TODO: this doesn't look right
210529bb91d6SAxel Dörfler 		// Small problem here, we can't use DormantNodeManager::PutAddOn(), as
210634c72144SAxel Dörfler 		// UnregisterNode() is called by a dormant node itself (by the
210734c72144SAxel Dörfler 		// destructor).
210854187cc6Sbeveloper 		// The add-on that contains the node needs to remain in memory until the
210954187cc6Sbeveloper 		// destructor execution is finished.
211029bb91d6SAxel Dörfler 		// DormantNodeManager::PutAddOnDelayed() will delay unloading.
21119c3b4706SAxel Dörfler 		gDormantNodeManager->PutAddOnDelayed(reply.add_on_id);
2112cf4e2277Sbeveloper 
211329bb91d6SAxel Dörfler 		status = MediaRosterEx(this)->DecrementAddonFlavorInstancesCount(
21149c3b4706SAxel Dörfler 			reply.add_on_id, reply.flavor_id);
211529bb91d6SAxel Dörfler 		if (status != B_OK) {
211634c72144SAxel Dörfler 			ERROR("BMediaRoster::UnregisterNode: "
211734c72144SAxel Dörfler 				"DecrementAddonFlavorInstancesCount() failed\n");
211854187cc6Sbeveloper 			// this is really a problem, but we can't fail now
211954187cc6Sbeveloper 		}
21208b04ffc1Sbeveloper 	}
21219e9417d2Sbeveloper 
21221299bfb2Sbeveloper 	// we are a friend class of BMediaNode and invalidate this member variable
21238b04ffc1Sbeveloper 	node->fNodeID = NODE_UNREGISTERED_ID;
21249e9417d2Sbeveloper 
2125c74afb57SJérôme Duval 	return status;
212652a38012Sejakowatz }
212752a38012Sejakowatz 
212852a38012Sejakowatz 
212934c72144SAxel Dörfler //!	Thread safe for multiple calls to Roster()
213052a38012Sejakowatz /*static*/ BMediaRoster*
213152a38012Sejakowatz BMediaRoster::Roster(status_t* out_error)
213252a38012Sejakowatz {
213352a38012Sejakowatz 	static BLocker locker("BMediaRoster::Roster locker");
213452a38012Sejakowatz 	locker.Lock();
21358496c38aSbeveloper 	if (out_error)
21368496c38aSbeveloper 		*out_error = B_OK;
21379def3bf7SStephan Aßmus 	if (sDefaultInstance == NULL) {
21388496c38aSbeveloper 		status_t err;
21399def3bf7SStephan Aßmus 		sDefaultInstance = new (std::nothrow) BMediaRosterEx(&err);
21409def3bf7SStephan Aßmus 		if (sDefaultInstance == NULL)
2141a715f908SStephan Aßmus 			err = B_NO_MEMORY;
2142a715f908SStephan Aßmus 		else if (err != B_OK) {
21439def3bf7SStephan Aßmus 			if (sDefaultInstance) {
21449def3bf7SStephan Aßmus 				sDefaultInstance->Lock();
21459def3bf7SStephan Aßmus 				sDefaultInstance->Quit();
21469def3bf7SStephan Aßmus 				sDefaultInstance = NULL;
2147dcfb6bfcSJérôme Duval 			}
21488496c38aSbeveloper 			if (out_error)
21498496c38aSbeveloper 				*out_error = err;
21508496c38aSbeveloper 		}
215152a38012Sejakowatz 	}
215252a38012Sejakowatz 	locker.Unlock();
21539def3bf7SStephan Aßmus 	return sDefaultInstance;
215452a38012Sejakowatz }
215552a38012Sejakowatz 
215652a38012Sejakowatz 
215752a38012Sejakowatz /*static*/ BMediaRoster*
215852a38012Sejakowatz BMediaRoster::CurrentRoster()
215952a38012Sejakowatz {
21609def3bf7SStephan Aßmus 	return sDefaultInstance;
216152a38012Sejakowatz }
216252a38012Sejakowatz 
216352a38012Sejakowatz 
216452a38012Sejakowatz status_t
216534c72144SAxel Dörfler BMediaRoster::SetTimeSourceFor(media_node_id node, media_node_id time_source)
216652a38012Sejakowatz {
2167aac800c2Sbeveloper 	CALLED();
216840f36b03Sbeveloper 	if (IS_INVALID_NODEID(node) || IS_INVALID_NODEID(time_source))
2169aac800c2Sbeveloper 		return B_BAD_VALUE;
2170aac800c2Sbeveloper 
2171aac800c2Sbeveloper 	media_node clone;
2172aac800c2Sbeveloper 	status_t rv, result;
2173aac800c2Sbeveloper 
2174332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SetTimeSourceFor: node %" B_PRId32 " will be assigned "
2175332cc6bcSAxel Dörfler 		"time source %" B_PRId32 "\n", node, time_source);
2176332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SetTimeSourceFor: node %" B_PRId32 " time source %"
2177332cc6bcSAxel Dörfler 		B_PRId32 " enter\n", node, time_source);
21785917dd5bSbeveloper 
217986bce45bSbeveloper 	// we need to get a clone of the node to have a port id
2180aac800c2Sbeveloper 	rv = GetNodeFor(node, &clone);
2181aac800c2Sbeveloper 	if (rv != B_OK) {
2182332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::SetTimeSourceFor, GetNodeFor failed, node id %"
2183332cc6bcSAxel Dörfler 			B_PRId32 "\n", node);
218452a38012Sejakowatz 		return B_ERROR;
218552a38012Sejakowatz 	}
218652a38012Sejakowatz 
218786bce45bSbeveloper 	// we just send the request to set time_source-id as timesource to the node,
218886bce45bSbeveloper 	// the NODE_SET_TIMESOURCE handler code will do the real assignment
2189aac800c2Sbeveloper 	result = B_OK;
2190aac800c2Sbeveloper 	node_set_timesource_command cmd;
2191aac800c2Sbeveloper 	cmd.timesource_id = time_source;
2192aac800c2Sbeveloper 	rv = SendToPort(clone.port, NODE_SET_TIMESOURCE, &cmd, sizeof(cmd));
2193aac800c2Sbeveloper 	if (rv != B_OK) {
219434c72144SAxel Dörfler 		ERROR("BMediaRoster::SetTimeSourceFor, sending NODE_SET_TIMESOURCE "
2195332cc6bcSAxel Dörfler 			"failed, node id %" B_PRId32 "\n", node);
2196aac800c2Sbeveloper 		result = B_ERROR;
2197aac800c2Sbeveloper 	}
2198aac800c2Sbeveloper 
219960f15390Sbeveloper 	// we release the clone
2200aac800c2Sbeveloper 	rv = ReleaseNode(clone);
2201aac800c2Sbeveloper 	if (rv != B_OK) {
2202332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::SetTimeSourceFor, ReleaseNode failed, node id %"
2203332cc6bcSAxel Dörfler 			B_PRId32 "\n", node);
2204aac800c2Sbeveloper 		result = B_ERROR;
2205aac800c2Sbeveloper 	}
2206aac800c2Sbeveloper 
2207332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SetTimeSourceFor: node %" B_PRId32 " time source %"
2208332cc6bcSAxel Dörfler 		B_PRId32 " leave\n", node, time_source);
22095917dd5bSbeveloper 
2210aac800c2Sbeveloper 	return result;
2211aac800c2Sbeveloper }
2212aac800c2Sbeveloper 
221352a38012Sejakowatz 
221452a38012Sejakowatz status_t
221534c72144SAxel Dörfler BMediaRoster::GetParameterWebFor(const media_node& node, BParameterWeb** _web)
221652a38012Sejakowatz {
221728ad138aSbeveloper 	CALLED();
221834c72144SAxel Dörfler 	if (_web == NULL)
221928ad138aSbeveloper 		return B_BAD_VALUE;
222028ad138aSbeveloper 	if (IS_INVALID_NODE(node))
222128ad138aSbeveloper 		return B_MEDIA_BAD_NODE;
222228ad138aSbeveloper 	if ((node.kind & B_CONTROLLABLE) == 0)
222328ad138aSbeveloper 		return B_MEDIA_BAD_NODE;
222428ad138aSbeveloper 
222528ad138aSbeveloper 	controllable_get_parameter_web_request request;
222628ad138aSbeveloper 	controllable_get_parameter_web_reply reply;
222734c72144SAxel Dörfler 	int32 requestsize[] = {B_PAGE_SIZE, 4 * B_PAGE_SIZE, 16 * B_PAGE_SIZE,
222834c72144SAxel Dörfler 		64 * B_PAGE_SIZE, 128 * B_PAGE_SIZE, 256 * B_PAGE_SIZE, 0};
222928ad138aSbeveloper 	int32 size;
223028ad138aSbeveloper 
223134c72144SAxel Dörfler 	// TODO: it might be better to query the node for the (current) parameter
223234c72144SAxel Dörfler 	// size first
223328ad138aSbeveloper 	for (int i = 0; (size = requestsize[i]) != 0; i++) {
223428ad138aSbeveloper 		status_t rv;
223528ad138aSbeveloper 		area_id area;
223628ad138aSbeveloper 		void *data;
223734c72144SAxel Dörfler 		area = create_area("parameter web data", &data, B_ANY_ADDRESS, size,
223834c72144SAxel Dörfler 			B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
223928ad138aSbeveloper 		if (area < B_OK) {
224034c72144SAxel Dörfler 			ERROR("BMediaRoster::GetParameterWebFor couldn't create area of "
2241332cc6bcSAxel Dörfler 				"size %" B_PRId32 "\n", size);
224228ad138aSbeveloper 			return B_ERROR;
224328ad138aSbeveloper 		}
224434c72144SAxel Dörfler 		request.max_size = size;
224528ad138aSbeveloper 		request.area = area;
224634c72144SAxel Dörfler 		rv = QueryPort(node.port, CONTROLLABLE_GET_PARAMETER_WEB, &request,
224734c72144SAxel Dörfler 			sizeof(request), &reply, sizeof(reply));
224828ad138aSbeveloper 		if (rv != B_OK) {
224934c72144SAxel Dörfler 			ERROR("BMediaRoster::GetParameterWebFor "
225034c72144SAxel Dörfler 				"CONTROLLABLE_GET_PARAMETER_WEB failed\n");
225128ad138aSbeveloper 			delete_area(area);
225228ad138aSbeveloper 			return B_ERROR;
225328ad138aSbeveloper 		}
225428ad138aSbeveloper 		if (reply.size == 0) {
225528ad138aSbeveloper 			// no parameter web available
225634c72144SAxel Dörfler 			// TODO: should we return an error?
2257332cc6bcSAxel Dörfler 			ERROR("BMediaRoster::GetParameterWebFor node %" B_PRId32
2258332cc6bcSAxel Dörfler 				" has no parameter web\n", node.node);
225934c72144SAxel Dörfler 			*_web = new (std::nothrow) BParameterWeb();
226028ad138aSbeveloper 			delete_area(area);
226134c72144SAxel Dörfler 			return *_web != NULL ? B_OK : B_NO_MEMORY;
226252a38012Sejakowatz 		}
226328ad138aSbeveloper 		if (reply.size > 0) {
226428ad138aSbeveloper 			// we got a flattened parameter web!
2265*df612ac9SRene Gollent 			BParameterWeb* web = new (std::nothrow) BParameterWeb();
2266*df612ac9SRene Gollent 			if (web == NULL)
2267a715f908SStephan Aßmus 				rv = B_NO_MEMORY;
2268a715f908SStephan Aßmus 			else {
2269332cc6bcSAxel Dörfler 				printf("BMediaRoster::GetParameterWebFor Unflattening %"
2270332cc6bcSAxel Dörfler 					B_PRId32 " bytes, %#" B_PRIx32 ", %#" B_PRIx32 ", %#"
2271332cc6bcSAxel Dörfler 					B_PRIx32 ", %#" B_PRIx32 "\n", reply.size,
2272332cc6bcSAxel Dörfler 					((uint32*)data)[0], ((uint32*)data)[1], ((uint32*)data)[2],
2273332cc6bcSAxel Dörfler 					((uint32*)data)[3]);
227428ad138aSbeveloper 
2275*df612ac9SRene Gollent 				rv = web->Unflatten(reply.code, data, reply.size);
227628ad138aSbeveloper 				if (rv != B_OK) {
227734c72144SAxel Dörfler 					ERROR("BMediaRoster::GetParameterWebFor Unflatten failed, "
227834c72144SAxel Dörfler 						"%s\n", strerror(rv));
2279*df612ac9SRene Gollent 					delete web;
2280*df612ac9SRene Gollent 				} else
2281*df612ac9SRene Gollent 					*_web = web;
228228ad138aSbeveloper 			}
2283*df612ac9SRene Gollent 
228428ad138aSbeveloper 			delete_area(area);
2285a715f908SStephan Aßmus 			return rv;
228628ad138aSbeveloper 		}
228728ad138aSbeveloper 		delete_area(area);
228828ad138aSbeveloper 		ASSERT(reply.size == -1);
228928ad138aSbeveloper 		// parameter web data was too large
229028ad138aSbeveloper 		// loop and try a larger size
229128ad138aSbeveloper 	}
2292332cc6bcSAxel Dörfler 	ERROR("BMediaRoster::GetParameterWebFor node %" B_PRId32 " has no "
2293332cc6bcSAxel Dörfler 		"parameter web larger than %" B_PRId32 "\n", node.node, size);
229428ad138aSbeveloper 	return B_ERROR;
229528ad138aSbeveloper }
229652a38012Sejakowatz 
229752a38012Sejakowatz 
229852a38012Sejakowatz status_t
229934c72144SAxel Dörfler BMediaRoster::StartControlPanel(const media_node& node, BMessenger* _messenger)
230052a38012Sejakowatz {
2301999cd0acSMaurice Kalinowski 	CALLED();
2302999cd0acSMaurice Kalinowski 
2303999cd0acSMaurice Kalinowski 	controllable_start_control_panel_request request;
2304999cd0acSMaurice Kalinowski 	controllable_start_control_panel_reply reply;
2305999cd0acSMaurice Kalinowski 
2306999cd0acSMaurice Kalinowski 	request.node = node;
2307999cd0acSMaurice Kalinowski 
2308999cd0acSMaurice Kalinowski 	status_t rv;
230934c72144SAxel Dörfler 	rv = QueryPort(node.port, CONTROLLABLE_START_CONTROL_PANEL, &request,
231034c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
2311999cd0acSMaurice Kalinowski 	if (rv != B_OK)
2312999cd0acSMaurice Kalinowski 		return rv;
2313999cd0acSMaurice Kalinowski 
231434c72144SAxel Dörfler 	if (reply.team != -1 && _messenger != NULL)
231534c72144SAxel Dörfler 		*_messenger = BMessenger(NULL, reply.team);
2316999cd0acSMaurice Kalinowski 
2317999cd0acSMaurice Kalinowski 	return B_OK;
231852a38012Sejakowatz }
231952a38012Sejakowatz 
232052a38012Sejakowatz 
232152a38012Sejakowatz status_t
232234c72144SAxel Dörfler BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count,
232334c72144SAxel Dörfler 	const media_format* hasInput, const media_format* hasOutput,
232434c72144SAxel Dörfler 	const char* name, uint64 requireKinds, uint64 denyKinds)
232552a38012Sejakowatz {
232652a38012Sejakowatz 	CALLED();
232734c72144SAxel Dörfler 	if (_info == NULL || _count == NULL || *_count <= 0)
232852a38012Sejakowatz 		return B_BAD_VALUE;
232952a38012Sejakowatz 
2330e4c87231SAxel Dörfler 	server_get_dormant_nodes_request request;
2331e4c87231SAxel Dörfler 	request.max_count = *_count;
2332e4c87231SAxel Dörfler 	request.has_input = hasInput != NULL;
233334c72144SAxel Dörfler 	if (hasInput != NULL) {
233434c72144SAxel Dörfler 		// TODO: we should not make a flat copy of media_format
2335e4c87231SAxel Dörfler 		request.input_format = *hasInput;
233634c72144SAxel Dörfler 	}
2337e4c87231SAxel Dörfler 	request.has_output = hasOutput != NULL;
233834c72144SAxel Dörfler 	if (hasOutput != NULL) {
233934c72144SAxel Dörfler 		// TODO: we should not make a flat copy of media_format
2340e4c87231SAxel Dörfler 		request.output_format = *hasOutput;
234134c72144SAxel Dörfler 	}
234234c72144SAxel Dörfler 
2343e4c87231SAxel Dörfler 	request.has_name = name != NULL;
2344e4c87231SAxel Dörfler 	if (name != NULL)
2345e4c87231SAxel Dörfler 		strlcpy(request.name, name, sizeof(request.name));
234652a38012Sejakowatz 
2347e4c87231SAxel Dörfler 	request.require_kinds = requireKinds;
2348e4c87231SAxel Dörfler 	request.deny_kinds = denyKinds;
234952a38012Sejakowatz 
2350e4c87231SAxel Dörfler 	server_get_dormant_nodes_reply reply;
2351e4c87231SAxel Dörfler 	status_t status = QueryServer(SERVER_GET_DORMANT_NODES, &request,
2352e4c87231SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
23536cafce94SAxel Dörfler 	if (status != B_OK)
2354e4c87231SAxel Dörfler 		return status;
235552a38012Sejakowatz 
235634c72144SAxel Dörfler 	*_count = reply.count;
235752a38012Sejakowatz 
2358e4c87231SAxel Dörfler 	if (reply.count > 0) {
2359e4c87231SAxel Dörfler 		int32 code;
2360e4c87231SAxel Dörfler 		status = read_port(request.reply_port, &code, _info,
2361e4c87231SAxel Dörfler 			reply.count * sizeof(dormant_node_info));
2362e4c87231SAxel Dörfler 		if (status < B_OK)
2363e4c87231SAxel Dörfler 			reply.result = status;
236452a38012Sejakowatz 	}
236552a38012Sejakowatz 
236652a38012Sejakowatz 	return reply.result;
236752a38012Sejakowatz }
236852a38012Sejakowatz 
2369e4c87231SAxel Dörfler 
237034c72144SAxel Dörfler /*!	This function is used to do the real work of instantiating a dormant node.
237134c72144SAxel Dörfler 	It is either called by the media_addon_server to instantiate a global node,
237234c72144SAxel Dörfler 	or it gets called from BMediaRoster::InstantiateDormantNode() to create a
237334c72144SAxel Dörfler 	local one.
237434c72144SAxel Dörfler 
237534c72144SAxel Dörfler 	Checks concerning global/local are not done here.
23768b04ffc1Sbeveloper */
237752a38012Sejakowatz status_t
237834c72144SAxel Dörfler BMediaRosterEx::InstantiateDormantNode(media_addon_id addonID, int32 flavorID,
237934c72144SAxel Dörfler 	team_id creator, media_node *_node)
238052a38012Sejakowatz {
238154187cc6Sbeveloper 	// This function is always called from the correct context, if the node
238254187cc6Sbeveloper 	// is supposed to be global, it is called from the media_addon_server.
238354187cc6Sbeveloper 
238452a38012Sejakowatz 	// if B_FLAVOR_IS_GLOBAL, we need to use the BMediaAddOn object that
238552a38012Sejakowatz 	// resides in the media_addon_server
238652a38012Sejakowatz 
23878b04ffc1Sbeveloper 	// RegisterNode() must be called for nodes instantiated from add-ons,
23888b04ffc1Sbeveloper 	// since the media kit warrants that it's done automatically.
238952a38012Sejakowatz 
239034c72144SAxel Dörfler 	// addonID		Indicates the ID number of the media add-on in which the
239134c72144SAxel Dörfler 	//				node resides.
239234c72144SAxel Dörfler 	// flavorID		Indicates the internal ID number that the add-on uses to
239334c72144SAxel Dörfler 	//				identify the flavor, this is the number that was published
239434c72144SAxel Dörfler 	//				by BMediaAddOn::GetFlavorAt() in the
23958b04ffc1Sbeveloper 	//				flavor_info::internal_id field.
239634c72144SAxel Dörfler 	// creator		The creator team is -1 if nodes are created locally. If
239734c72144SAxel Dörfler 	//				created globally, it will contain (while called in
239834c72144SAxel Dörfler 	//				media_addon_server context) the team-id of the team that
239934c72144SAxel Dörfler 	//				requested the instantiation.
24008b04ffc1Sbeveloper 
2401332cc6bcSAxel Dörfler 	TRACE("BMediaRosterEx::InstantiateDormantNode: addonID %" B_PRId32
2402332cc6bcSAxel Dörfler 		", flavorID %" B_PRId32 "\n", addonID, flavorID);
24038b04ffc1Sbeveloper 
24048b04ffc1Sbeveloper 	// Get flavor_info from the server
240534c72144SAxel Dörfler 	dormant_flavor_info info;
24068c6a6096Sbeveloper 	status_t rv;
240734c72144SAxel Dörfler 	rv = GetDormantFlavorInfo(addonID, flavorID, &info);
24088b04ffc1Sbeveloper 	if (rv != B_OK) {
240934c72144SAxel Dörfler 		ERROR("BMediaRosterEx::InstantiateDormantNode error: failed to get "
2410332cc6bcSAxel Dörfler 			"dormant_flavor_info for addon-id %" B_PRId32 ", flavor-id %"
2411332cc6bcSAxel Dörfler 			B_PRId32 "\n", addonID, flavorID);
241252a38012Sejakowatz 		return B_ERROR;
241352a38012Sejakowatz 	}
24148b04ffc1Sbeveloper 
24151ecccf18SFrançois Revol 	ASSERT(info.internal_id == flavorID);
24168b04ffc1Sbeveloper 
24178b04ffc1Sbeveloper 	// load the BMediaAddOn object
241829bb91d6SAxel Dörfler 	BMediaAddOn* addon = gDormantNodeManager->GetAddOn(addonID);
241934c72144SAxel Dörfler 	if (addon == NULL) {
24205ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::InstantiateDormantNode: GetAddon failed\n");
24218b04ffc1Sbeveloper 		return B_ERROR;
24228b04ffc1Sbeveloper 	}
24238b04ffc1Sbeveloper 
242454187cc6Sbeveloper 	// Now we need to try to increment the use count of this addon flavor
242554187cc6Sbeveloper 	// in the server. This can fail if the total number instances of this
242654187cc6Sbeveloper 	// flavor is limited.
242734c72144SAxel Dörfler 	rv = IncrementAddonFlavorInstancesCount(addonID, flavorID);
242854187cc6Sbeveloper 	if (rv != B_OK) {
242934c72144SAxel Dörfler 		ERROR("BMediaRosterEx::InstantiateDormantNode error: can't create "
2430332cc6bcSAxel Dörfler 			"more nodes for addon-id %" B_PRId32 ", flavor-id %" B_PRId32 "\n",
2431332cc6bcSAxel Dörfler 			addonID, flavorID);
243254187cc6Sbeveloper 		// Put the addon back into the pool
243329bb91d6SAxel Dörfler 		gDormantNodeManager->PutAddOn(addonID);
243454187cc6Sbeveloper 		return B_ERROR;
243554187cc6Sbeveloper 	}
243654187cc6Sbeveloper 
24378b04ffc1Sbeveloper 	BMessage config;
243834c72144SAxel Dörfler 	rv = LoadNodeConfiguration(addonID, flavorID, &config);
243954187cc6Sbeveloper 	if (rv != B_OK) {
244034c72144SAxel Dörfler 		ERROR("BMediaRosterEx::InstantiateDormantNode: couldn't load "
2441332cc6bcSAxel Dörfler 			"configuration for addon-id %" B_PRId32 ", flavor-id %" B_PRId32
2442332cc6bcSAxel Dörfler 			"\n", addonID, flavorID);
244354187cc6Sbeveloper 		// do not return, this is a minor problem, not a reason to fail
244454187cc6Sbeveloper 	}
24458b04ffc1Sbeveloper 
244634c72144SAxel Dörfler 	status_t status = B_OK;
244734c72144SAxel Dörfler 	BMediaNode* node = addon->InstantiateNodeFor(&info, &config, &status);
244834c72144SAxel Dörfler 	if (node == NULL) {
244934c72144SAxel Dörfler 		ERROR("BMediaRosterEx::InstantiateDormantNode: InstantiateNodeFor "
245034c72144SAxel Dörfler 			"failed\n");
24518b04ffc1Sbeveloper 
245254187cc6Sbeveloper 		// Put the addon back into the pool
245329bb91d6SAxel Dörfler 		gDormantNodeManager->PutAddOn(addonID);
245434c72144SAxel Dörfler 
245554187cc6Sbeveloper 		// We must decrement the use count of this addon flavor in the
245654187cc6Sbeveloper 		// server to compensate the increment done in the beginning.
245734c72144SAxel Dörfler 		rv = DecrementAddonFlavorInstancesCount(addonID, flavorID);
245854187cc6Sbeveloper 		if (rv != B_OK) {
245934c72144SAxel Dörfler 			ERROR("BMediaRosterEx::InstantiateDormantNode: DecrementAddon"
246034c72144SAxel Dörfler 				"FlavorInstancesCount failed\n");
246116b7eea4Sbeveloper 		}
246234c72144SAxel Dörfler 		return status != B_OK ? status : B_ERROR;
246354187cc6Sbeveloper 	}
246454187cc6Sbeveloper 
246534c72144SAxel Dörfler 	rv = RegisterNode(node, addonID, flavorID);
24668c6a6096Sbeveloper 	if (rv != B_OK) {
24675ac4fbd7Sbeveloper 		ERROR("BMediaRosterEx::InstantiateDormantNode: RegisterNode failed\n");
24688c6a6096Sbeveloper 		delete node;
246954187cc6Sbeveloper 		// Put the addon back into the pool
247029bb91d6SAxel Dörfler 		gDormantNodeManager->PutAddOn(addonID);
247154187cc6Sbeveloper 		// We must decrement the use count of this addon flavor in the
247254187cc6Sbeveloper 		// server to compensate the increment done in the beginning.
247334c72144SAxel Dörfler 		rv = DecrementAddonFlavorInstancesCount(addonID, flavorID);
247454187cc6Sbeveloper 		if (rv != B_OK) {
247534c72144SAxel Dörfler 			ERROR("BMediaRosterEx::InstantiateDormantNode: DecrementAddon"
247634c72144SAxel Dörfler 				"FlavorInstancesCount failed\n");
247754187cc6Sbeveloper 		}
24788c6a6096Sbeveloper 		return B_ERROR;
24798c6a6096Sbeveloper 	}
24808c6a6096Sbeveloper 
248154187cc6Sbeveloper 	if (creator != -1) {
248234c72144SAxel Dörfler 		// send a message to the server to assign team "creator" as creator
248334c72144SAxel Dörfler 		// of node "node->ID()"
2484332cc6bcSAxel Dörfler 		printf("!!! BMediaRosterEx::InstantiateDormantNode assigning team %"
2485332cc6bcSAxel Dörfler 			B_PRId32 " as creator of node %" B_PRId32 "\n", creator,
2486332cc6bcSAxel Dörfler 			node->ID());
248734c72144SAxel Dörfler 
248854187cc6Sbeveloper 		rv = MediaRosterEx(this)->SetNodeCreator(node->ID(), creator);
248954187cc6Sbeveloper 		if (rv != B_OK) {
249034c72144SAxel Dörfler 			ERROR("BMediaRosterEx::InstantiateDormantNode failed to assign "
2491332cc6bcSAxel Dörfler 				"team %" B_PRId32 " as creator of node %" B_PRId32 "\n",
2492332cc6bcSAxel Dörfler 				creator, node->ID());
249354187cc6Sbeveloper 			// do not return, this is a minor problem, not a reason to fail
249454187cc6Sbeveloper 		}
249554187cc6Sbeveloper 	}
249654187cc6Sbeveloper 
249754187cc6Sbeveloper 	// RegisterNode() does remember the add-on id in the server
249854187cc6Sbeveloper 	// and UnregisterNode() will call DormantNodeManager::PutAddon()
249954187cc6Sbeveloper 	// when the node is unregistered.
25008c6a6096Sbeveloper 
250134c72144SAxel Dörfler 	*_node = node->Node();
2502cf4e2277Sbeveloper 
2503332cc6bcSAxel Dörfler 	TRACE("BMediaRosterEx::InstantiateDormantNode: addon-id %" B_PRId32
2504332cc6bcSAxel Dörfler 		", flavor_id %" B_PRId32 " instanciated as node %" B_PRId32 ", port %"
2505332cc6bcSAxel Dörfler 		B_PRId32 " in team %" B_PRId32 "\n", addonID, flavorID, _node->node,
2506332cc6bcSAxel Dörfler 		_node->port, BPrivate::current_team());
2507cf4e2277Sbeveloper 
250816b7eea4Sbeveloper 	return B_OK;
250916b7eea4Sbeveloper }
251052a38012Sejakowatz 
251152a38012Sejakowatz 
251252a38012Sejakowatz status_t
251334c72144SAxel Dörfler BMediaRoster::InstantiateDormantNode(const dormant_node_info& info,
251434c72144SAxel Dörfler 	media_node* _node, uint32 flags)
25158b04ffc1Sbeveloper {
25168b04ffc1Sbeveloper 	CALLED();
251734c72144SAxel Dörfler 	if (_node == NULL)
25188b04ffc1Sbeveloper 		return B_BAD_VALUE;
251934c72144SAxel Dörfler 	if (info.addon <= B_OK) {
2520332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::InstantiateDormantNode error: addon-id %" B_PRId32
252134c72144SAxel Dörfler 			" invalid.\n", info.addon);
25228b04ffc1Sbeveloper 		return B_BAD_VALUE;
25238b04ffc1Sbeveloper 	}
25248b04ffc1Sbeveloper 
2525332cc6bcSAxel Dörfler 	printf("BMediaRoster::InstantiateDormantNode: addon-id %" B_PRId32
2526332cc6bcSAxel Dörfler 		", flavor_id %" B_PRId32 ", flags 0x%" B_PRIx32 "\n", info.addon,
2527332cc6bcSAxel Dörfler 		info.flavor_id, flags);
25288b04ffc1Sbeveloper 
25298b04ffc1Sbeveloper 	// Get flavor_info from the server
253034c72144SAxel Dörfler 	// TODO: this is a little overhead, as we get the full blown
253134c72144SAxel Dörfler 	// dormant_flavor_info,
253234c72144SAxel Dörfler 	// TODO: but only need the flags.
253334c72144SAxel Dörfler 	dormant_flavor_info flavorInfo;
25348b04ffc1Sbeveloper 	status_t rv;
253534c72144SAxel Dörfler 	rv = MediaRosterEx(this)->GetDormantFlavorInfo(info.addon, info.flavor_id,
253634c72144SAxel Dörfler 		&flavorInfo);
25378b04ffc1Sbeveloper 	if (rv != B_OK) {
253834c72144SAxel Dörfler 		ERROR("BMediaRoster::InstantiateDormantNode: failed to get "
2539332cc6bcSAxel Dörfler 			"dormant_flavor_info for addon-id %" B_PRId32 ", flavor-id %"
2540332cc6bcSAxel Dörfler 			B_PRId32 "\n", info.addon, info.flavor_id);
2541626824eaSbeveloper 		return B_NAME_NOT_FOUND;
25428b04ffc1Sbeveloper 	}
25438b04ffc1Sbeveloper 
254434c72144SAxel Dörfler 	ASSERT(flavorInfo.internal_id == info.flavor_id);
25458b04ffc1Sbeveloper 
25468b04ffc1Sbeveloper #if DEBUG
254734c72144SAxel Dörfler 	printf("BMediaRoster::InstantiateDormantNode: name \"%s\", info \"%s\", "
2548332cc6bcSAxel Dörfler 		"flavor_flags 0x%" B_PRIx32 ", internal_id %" B_PRId32
2549332cc6bcSAxel Dörfler 		", possible_count %" B_PRId32 "\n", flavorInfo.name, flavorInfo.info,
2550332cc6bcSAxel Dörfler 		flavorInfo.flavor_flags, flavorInfo.internal_id,
2551332cc6bcSAxel Dörfler 		flavorInfo.possible_count);
255234c72144SAxel Dörfler 
255334c72144SAxel Dörfler 	if ((flags & B_FLAVOR_IS_LOCAL) != 0) {
255434c72144SAxel Dörfler 		printf("BMediaRoster::InstantiateDormantNode: caller requested "
255534c72144SAxel Dörfler 			"B_FLAVOR_IS_LOCAL\n");
255634c72144SAxel Dörfler 	}
255734c72144SAxel Dörfler 	if ((flags & B_FLAVOR_IS_GLOBAL) != 0) {
255834c72144SAxel Dörfler 		printf("BMediaRoster::InstantiateDormantNode: caller requested "
255934c72144SAxel Dörfler 			"B_FLAVOR_IS_GLOBAL\n");
256034c72144SAxel Dörfler 	}
256134c72144SAxel Dörfler 	if ((flavorInfo.flavor_flags & B_FLAVOR_IS_LOCAL) != 0) {
256234c72144SAxel Dörfler 		printf("BMediaRoster::InstantiateDormantNode: node requires "
256334c72144SAxel Dörfler 			"B_FLAVOR_IS_LOCAL\n");
256434c72144SAxel Dörfler 	}
256534c72144SAxel Dörfler 	if ((flavorInfo.flavor_flags & B_FLAVOR_IS_GLOBAL) != 0) {
256634c72144SAxel Dörfler 		printf("BMediaRoster::InstantiateDormantNode: node requires "
256734c72144SAxel Dörfler 			"B_FLAVOR_IS_GLOBAL\n");
256834c72144SAxel Dörfler 	}
25698b04ffc1Sbeveloper #endif
25708b04ffc1Sbeveloper 
25718b04ffc1Sbeveloper 	// Make sure that flags demanded by the dormant node and those requested
25728b04ffc1Sbeveloper 	// by the caller are not incompatible.
257334c72144SAxel Dörfler 	if ((flavorInfo.flavor_flags & B_FLAVOR_IS_GLOBAL) != 0
257434c72144SAxel Dörfler 		&& (flags & B_FLAVOR_IS_LOCAL) != 0) {
257534c72144SAxel Dörfler 		ERROR("BMediaRoster::InstantiateDormantNode: requested "
257634c72144SAxel Dörfler 			"B_FLAVOR_IS_LOCAL, but dormant node has B_FLAVOR_IS_GLOBAL\n");
2577626824eaSbeveloper 		return B_NAME_NOT_FOUND;
25788b04ffc1Sbeveloper 	}
257934c72144SAxel Dörfler 	if ((flavorInfo.flavor_flags & B_FLAVOR_IS_LOCAL) != 0
258034c72144SAxel Dörfler 		&& (flags & B_FLAVOR_IS_GLOBAL) != 0) {
258134c72144SAxel Dörfler 		ERROR("BMediaRoster::InstantiateDormantNode: requested "
258234c72144SAxel Dörfler 			"B_FLAVOR_IS_GLOBAL, but dormant node has B_FLAVOR_IS_LOCAL\n");
2583626824eaSbeveloper 		return B_NAME_NOT_FOUND;
25848b04ffc1Sbeveloper 	}
258554187cc6Sbeveloper 
25868b04ffc1Sbeveloper 	// If either the node, or the caller requested to make the instance global
258734c72144SAxel Dörfler 	// we will do it by forwarding this request into the media_addon_server,
258834c72144SAxel Dörfler 	// which in turn will call BMediaRosterEx::InstantiateDormantNode to create
258934c72144SAxel Dörfler 	// the node there and make it globally available.
259034c72144SAxel Dörfler 	if ((flavorInfo.flavor_flags & B_FLAVOR_IS_GLOBAL) != 0
259134c72144SAxel Dörfler 		|| (flags & B_FLAVOR_IS_GLOBAL) != 0) {
259234c72144SAxel Dörfler 		TRACE("BMediaRoster::InstantiateDormantNode: creating global object "
259334c72144SAxel Dörfler 			"in media_addon_server\n");
2594cf4e2277Sbeveloper 
25959c3b4706SAxel Dörfler 		add_on_server_instantiate_dormant_node_request request;
25969c3b4706SAxel Dörfler 		add_on_server_instantiate_dormant_node_reply reply;
25979c3b4706SAxel Dörfler 		request.add_on_id = info.addon;
25989dec2310SAxel Dörfler 		request.flavor_id = info.flavor_id;
25999dec2310SAxel Dörfler 		request.creator_team = BPrivate::current_team();
260034c72144SAxel Dörfler 			// creator team is allowed to also release global nodes
26019c3b4706SAxel Dörfler 		rv = QueryAddOnServer(ADD_ON_SERVER_INSTANTIATE_DORMANT_NODE, &request,
260234c72144SAxel Dörfler 			sizeof(request), &reply, sizeof(reply));
260334c72144SAxel Dörfler 		if (rv == B_OK)
260434c72144SAxel Dörfler 			*_node = reply.node;
26058b04ffc1Sbeveloper 	} else {
260654187cc6Sbeveloper 		// creator team = -1, as this is a local node
260734c72144SAxel Dörfler 		rv = MediaRosterEx(this)->InstantiateDormantNode(info.addon,
260834c72144SAxel Dörfler 			info.flavor_id, -1, _node);
26098b04ffc1Sbeveloper 	}
2610626824eaSbeveloper 	if (rv != B_OK) {
261134c72144SAxel Dörfler 		*_node = media_node::null;
2612626824eaSbeveloper 		return B_NAME_NOT_FOUND;
2613626824eaSbeveloper 	}
2614626824eaSbeveloper 	return B_OK;
26158b04ffc1Sbeveloper }
26168b04ffc1Sbeveloper 
26178b04ffc1Sbeveloper 
26188b04ffc1Sbeveloper status_t
261934c72144SAxel Dörfler BMediaRoster::InstantiateDormantNode(const dormant_node_info& info,
262034c72144SAxel Dörfler 	media_node* _node)
26218b04ffc1Sbeveloper {
262234c72144SAxel Dörfler 	return InstantiateDormantNode(info, _node, 0);
26238b04ffc1Sbeveloper }
26248b04ffc1Sbeveloper 
26258b04ffc1Sbeveloper 
26268b04ffc1Sbeveloper status_t
262752a38012Sejakowatz BMediaRoster::GetDormantNodeFor(const media_node& node,
262834c72144SAxel Dörfler 	dormant_node_info* _info)
262952a38012Sejakowatz {
263085dfab2bSbeveloper 	CALLED();
263134c72144SAxel Dörfler 	if (_info == NULL)
263285dfab2bSbeveloper 		return B_BAD_VALUE;
263340f36b03Sbeveloper 	if (IS_INVALID_NODE(node))
263485dfab2bSbeveloper 		return B_MEDIA_BAD_NODE;
263552a38012Sejakowatz 
263685dfab2bSbeveloper 	server_get_dormant_node_for_request request;
263785dfab2bSbeveloper 	server_get_dormant_node_for_reply reply;
263885dfab2bSbeveloper 	status_t rv;
263985dfab2bSbeveloper 
264085dfab2bSbeveloper 	request.node = node;
264185dfab2bSbeveloper 
264234c72144SAxel Dörfler 	rv = QueryServer(SERVER_GET_DORMANT_NODE_FOR, &request, sizeof(request),
264334c72144SAxel Dörfler 		&reply, sizeof(reply));
264485dfab2bSbeveloper 	if (rv != B_OK)
264585dfab2bSbeveloper 		return rv;
264685dfab2bSbeveloper 
264734c72144SAxel Dörfler 	*_info = reply.node_info;
264885dfab2bSbeveloper 	return B_OK;
264952a38012Sejakowatz }
265052a38012Sejakowatz 
265134c72144SAxel Dörfler 
265252a38012Sejakowatz status_t
265334c72144SAxel Dörfler BMediaRosterEx::GetDormantFlavorInfo(media_addon_id addonID, int32 flavorID,
265434c72144SAxel Dörfler 	dormant_flavor_info* _flavor)
265552a38012Sejakowatz {
265652a38012Sejakowatz 	CALLED();
265734c72144SAxel Dörfler 	if (_flavor == NULL)
26589bedd42cSbeveloper 		return B_BAD_VALUE;
265952a38012Sejakowatz 
2660e4c87231SAxel Dörfler 	// TODO: better use an area here as well!
266152a38012Sejakowatz 
2662e4c87231SAxel Dörfler 	server_get_dormant_flavor_info_reply* reply
2663e4c87231SAxel Dörfler 		= (server_get_dormant_flavor_info_reply*)malloc(16300);
266434c72144SAxel Dörfler 	if (reply == NULL)
266534c72144SAxel Dörfler 		return B_NO_MEMORY;
266652a38012Sejakowatz 
2667e4c87231SAxel Dörfler 	server_get_dormant_flavor_info_request request;
2668e4c87231SAxel Dörfler 	request.add_on_id = addonID;
2669e4c87231SAxel Dörfler 	request.flavor_id = flavorID;
2670e4c87231SAxel Dörfler 
2671e4c87231SAxel Dörfler 	status_t status = QueryServer(SERVER_GET_DORMANT_FLAVOR_INFO, &request,
2672e4c87231SAxel Dörfler 		sizeof(request), reply, 16300);
26739dec2310SAxel Dörfler 	if (status != B_OK) {
267452a38012Sejakowatz 		free(reply);
26759dec2310SAxel Dörfler 		return status;
267652a38012Sejakowatz 	}
267752a38012Sejakowatz 
26789dec2310SAxel Dörfler 	if (reply->result == B_OK) {
26799dec2310SAxel Dörfler 		status = _flavor->Unflatten(reply->type, &reply->flattened_data,
26809dec2310SAxel Dörfler 			reply->flattened_size);
26819dec2310SAxel Dörfler 	} else
26829dec2310SAxel Dörfler 		status = reply->result;
268352a38012Sejakowatz 
268452a38012Sejakowatz 	free(reply);
26859dec2310SAxel Dörfler 	return status;
268652a38012Sejakowatz }
268752a38012Sejakowatz 
268834c72144SAxel Dörfler 
26898b04ffc1Sbeveloper status_t
269034c72144SAxel Dörfler BMediaRoster::GetDormantFlavorInfoFor(const dormant_node_info& dormant,
269134c72144SAxel Dörfler 	dormant_flavor_info* _flavor)
26928b04ffc1Sbeveloper {
269334c72144SAxel Dörfler 	return MediaRosterEx(this)->GetDormantFlavorInfo(dormant.addon,
269434c72144SAxel Dörfler 		dormant.flavor_id, _flavor);
26958b04ffc1Sbeveloper }
269652a38012Sejakowatz 
269734c72144SAxel Dörfler 
269860f15390Sbeveloper // Reports in outLatency the maximum latency found downstream from
269960f15390Sbeveloper // the specified BBufferProducer, producer, given the current connections.
270052a38012Sejakowatz status_t
270134c72144SAxel Dörfler BMediaRoster::GetLatencyFor(const media_node& producer, bigtime_t* _latency)
270252a38012Sejakowatz {
270360f15390Sbeveloper 	CALLED();
270434c72144SAxel Dörfler 	if (_latency == NULL)
270560f15390Sbeveloper 		return B_BAD_VALUE;
270634c72144SAxel Dörfler 	if (IS_INVALID_NODE(producer)
270734c72144SAxel Dörfler 		|| (producer.kind & B_BUFFER_PRODUCER) == 0)
270860f15390Sbeveloper 		return B_MEDIA_BAD_NODE;
270960f15390Sbeveloper 
271060f15390Sbeveloper 	producer_get_latency_request request;
271160f15390Sbeveloper 	producer_get_latency_reply reply;
271260f15390Sbeveloper 	status_t rv;
271360f15390Sbeveloper 
271434c72144SAxel Dörfler 	rv = QueryPort(producer.port, PRODUCER_GET_LATENCY, &request,
271534c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
271660f15390Sbeveloper 	if (rv != B_OK)
271760f15390Sbeveloper 		return rv;
271860f15390Sbeveloper 
271934c72144SAxel Dörfler 	*_latency = reply.latency;
272060f15390Sbeveloper 
2721ab9afde3SMarcus Overhagen //	printf("BMediaRoster::GetLatencyFor producer %ld has maximum latency %Ld\n", producer.node, *out_latency);
2722aac800c2Sbeveloper 	return B_OK;
272352a38012Sejakowatz }
272452a38012Sejakowatz 
272552a38012Sejakowatz 
272652a38012Sejakowatz status_t
272752a38012Sejakowatz BMediaRoster::GetInitialLatencyFor(const media_node& producer,
272834c72144SAxel Dörfler 	bigtime_t* _latency, uint32* _flags)
272952a38012Sejakowatz {
2730b65a0ac5SJérôme Duval 	CALLED();
273134c72144SAxel Dörfler 	if (_latency == NULL)
2732b65a0ac5SJérôme Duval 		return B_BAD_VALUE;
273334c72144SAxel Dörfler 	if (IS_INVALID_NODE(producer)
273434c72144SAxel Dörfler 		|| (producer.kind & B_BUFFER_PRODUCER) == 0)
2735b65a0ac5SJérôme Duval 		return B_MEDIA_BAD_NODE;
2736b65a0ac5SJérôme Duval 
2737b65a0ac5SJérôme Duval 	producer_get_initial_latency_request request;
2738b65a0ac5SJérôme Duval 	producer_get_initial_latency_reply reply;
2739b65a0ac5SJérôme Duval 	status_t rv;
2740b65a0ac5SJérôme Duval 
274134c72144SAxel Dörfler 	rv = QueryPort(producer.port, PRODUCER_GET_INITIAL_LATENCY, &request,
274234c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
2743b65a0ac5SJérôme Duval 	if (rv != B_OK)
2744b65a0ac5SJérôme Duval 		return rv;
2745b65a0ac5SJérôme Duval 
274634c72144SAxel Dörfler 	*_latency = reply.initial_latency;
274734c72144SAxel Dörfler 	if (_flags != NULL)
274834c72144SAxel Dörfler 		*_flags = reply.flags;
2749b65a0ac5SJérôme Duval 
2750332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::GetInitialLatencyFor producer %" B_PRId32 " has "
2751332cc6bcSAxel Dörfler 		"maximum initial latency %" B_PRId64 "\n", producer.node, *_latency);
2752aac800c2Sbeveloper 	return B_OK;
275352a38012Sejakowatz }
275452a38012Sejakowatz 
275552a38012Sejakowatz 
275652a38012Sejakowatz status_t
275734c72144SAxel Dörfler BMediaRoster::GetStartLatencyFor(const media_node& timeSource,
275834c72144SAxel Dörfler 	bigtime_t* _latency)
275952a38012Sejakowatz {
2760fc8b28b6SJérôme Duval 	CALLED();
276134c72144SAxel Dörfler 	if (_latency == NULL)
2762fc8b28b6SJérôme Duval 		return B_BAD_VALUE;
276334c72144SAxel Dörfler 	if (IS_INVALID_NODE(timeSource)
276434c72144SAxel Dörfler 		|| (timeSource.kind & B_TIME_SOURCE) == 0)
2765fc8b28b6SJérôme Duval 		return B_MEDIA_BAD_NODE;
2766fc8b28b6SJérôme Duval 
2767fc8b28b6SJérôme Duval 	timesource_get_start_latency_request request;
2768fc8b28b6SJérôme Duval 	timesource_get_start_latency_reply reply;
2769fc8b28b6SJérôme Duval 	status_t rv;
2770fc8b28b6SJérôme Duval 
277134c72144SAxel Dörfler 	rv = QueryPort(timeSource.port, TIMESOURCE_GET_START_LATENCY, &request,
277234c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
2773fc8b28b6SJérôme Duval 	if (rv != B_OK)
2774fc8b28b6SJérôme Duval 		return rv;
2775fc8b28b6SJérôme Duval 
277634c72144SAxel Dörfler 	*_latency = reply.start_latency;
2777fc8b28b6SJérôme Duval 
2778332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::GetStartLatencyFor timesource %" B_PRId32 " has "
2779332cc6bcSAxel Dörfler 		"maximum initial latency %" B_PRId64 "\n", timeSource.node, *_latency);
2780aac800c2Sbeveloper 	return B_OK;
278152a38012Sejakowatz }
278252a38012Sejakowatz 
278352a38012Sejakowatz 
278452a38012Sejakowatz status_t
278534c72144SAxel Dörfler BMediaRoster::GetFileFormatsFor(const media_node& fileInterface,
278634c72144SAxel Dörfler 	media_file_format* _formats, int32* _numFormats)
278752a38012Sejakowatz {
278852a38012Sejakowatz 	UNIMPLEMENTED();
278952a38012Sejakowatz 	return B_ERROR;
279052a38012Sejakowatz }
279152a38012Sejakowatz 
279252a38012Sejakowatz 
279352a38012Sejakowatz status_t
279434c72144SAxel Dörfler BMediaRoster::SetRefFor(const media_node& file_interface, const entry_ref& file,
279534c72144SAxel Dörfler 	bool createAndTruncate, bigtime_t* _length)
279652a38012Sejakowatz {
27976938364bSMaurice Kalinowski 	CALLED();
27986938364bSMaurice Kalinowski 
27996938364bSMaurice Kalinowski 	fileinterface_set_ref_request request;
28006938364bSMaurice Kalinowski 	fileinterface_set_ref_reply reply;
28016938364bSMaurice Kalinowski 	status_t rv;
28026938364bSMaurice Kalinowski 
28036938364bSMaurice Kalinowski 	request.device = file.device;
28046938364bSMaurice Kalinowski 	request.directory = file.directory;
28056938364bSMaurice Kalinowski 	strcpy(request.name, file.name);
280634c72144SAxel Dörfler 	request.create = createAndTruncate;
280734c72144SAxel Dörfler 	if (_length != NULL)
280834c72144SAxel Dörfler 		request.duration = *_length;
28096938364bSMaurice Kalinowski 
281034c72144SAxel Dörfler 	rv = QueryPort(file_interface.port, FILEINTERFACE_SET_REF, &request,
281134c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
28126938364bSMaurice Kalinowski 	if (rv != B_OK)
28136938364bSMaurice Kalinowski 		return rv;
28146938364bSMaurice Kalinowski 
281534c72144SAxel Dörfler 	if (!createAndTruncate && _length)
281634c72144SAxel Dörfler 		*_length = reply.duration;
28176938364bSMaurice Kalinowski 
28186938364bSMaurice Kalinowski 	return B_OK;
281952a38012Sejakowatz }
282052a38012Sejakowatz 
282152a38012Sejakowatz 
282252a38012Sejakowatz status_t
282334c72144SAxel Dörfler BMediaRoster::GetRefFor(const media_node& node, entry_ref* _file,
282434c72144SAxel Dörfler 	BMimeType* mimeType)
282552a38012Sejakowatz {
28266938364bSMaurice Kalinowski 	CALLED();
28276938364bSMaurice Kalinowski 
282834c72144SAxel Dörfler 	if (!_file)
28296938364bSMaurice Kalinowski 		return B_BAD_VALUE;
28306938364bSMaurice Kalinowski 
28316938364bSMaurice Kalinowski 	fileinterface_get_ref_request request;
28326938364bSMaurice Kalinowski 	fileinterface_get_ref_reply reply;
28336938364bSMaurice Kalinowski 	status_t rv;
28346938364bSMaurice Kalinowski 
283534c72144SAxel Dörfler 	rv = QueryPort(node.port, FILEINTERFACE_GET_REF, &request, sizeof(request),
283634c72144SAxel Dörfler 		&reply, sizeof(reply));
28376938364bSMaurice Kalinowski 	if (rv != B_OK)
28386938364bSMaurice Kalinowski 		return rv;
28396938364bSMaurice Kalinowski 
284034c72144SAxel Dörfler 	*_file = entry_ref(reply.device, reply.directory, reply.name);
28416938364bSMaurice Kalinowski 
284234c72144SAxel Dörfler 	if (mimeType)
284334c72144SAxel Dörfler 		mimeType->SetTo(reply.mimetype);
28446938364bSMaurice Kalinowski 
28456938364bSMaurice Kalinowski 	return B_OK;
284652a38012Sejakowatz }
284752a38012Sejakowatz 
284852a38012Sejakowatz 
284952a38012Sejakowatz status_t
285052a38012Sejakowatz BMediaRoster::SniffRefFor(const media_node& file_interface,
285134c72144SAxel Dörfler 	const entry_ref& file, BMimeType* mimeType, float* _capability)
285252a38012Sejakowatz {
28536938364bSMaurice Kalinowski 	CALLED();
285434c72144SAxel Dörfler 	if (mimeType == NULL || _capability == NULL)
28556938364bSMaurice Kalinowski 		return B_BAD_VALUE;
28566938364bSMaurice Kalinowski 
28576938364bSMaurice Kalinowski 	fileinterface_sniff_ref_request request;
28586938364bSMaurice Kalinowski 	fileinterface_sniff_ref_reply reply;
28596938364bSMaurice Kalinowski 	status_t rv;
28606938364bSMaurice Kalinowski 
28616938364bSMaurice Kalinowski 	request.device = file.device;
28626938364bSMaurice Kalinowski 	request.directory = file.directory;
28636938364bSMaurice Kalinowski 	strcpy(request.name, file.name);
28646938364bSMaurice Kalinowski 
286534c72144SAxel Dörfler 	rv = QueryPort(file_interface.port, FILEINTERFACE_SNIFF_REF, &request,
286634c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
28676938364bSMaurice Kalinowski 	if (rv != B_OK)
28686938364bSMaurice Kalinowski 		return rv;
28696938364bSMaurice Kalinowski 
287034c72144SAxel Dörfler 	mimeType->SetTo(reply.mimetype);
287134c72144SAxel Dörfler 	*_capability = reply.capability;
28726938364bSMaurice Kalinowski 
28736938364bSMaurice Kalinowski 	return B_OK;
287452a38012Sejakowatz }
287552a38012Sejakowatz 
287652a38012Sejakowatz 
287734c72144SAxel Dörfler /*!	This is the generic "here's a file, now can someone please play it"
287834c72144SAxel Dörfler 	interface.
287934c72144SAxel Dörfler */
288052a38012Sejakowatz status_t
288134c72144SAxel Dörfler BMediaRoster::SniffRef(const entry_ref& file, uint64 requireNodeKinds,
288234c72144SAxel Dörfler 	dormant_node_info* _node, BMimeType* mimeType)
288352a38012Sejakowatz {
288405f452c3SDavid McPaul 	CALLED();
288505f452c3SDavid McPaul 
2886332cc6bcSAxel Dörfler 	TRACE("BMediaRoster::SniffRef looking for a node to handle %s: 0x%" B_PRIx64
2887332cc6bcSAxel Dörfler 		"\n", file.name, requireNodeKinds);
288805f452c3SDavid McPaul 
288905f452c3SDavid McPaul 	if (_node == NULL)
289005f452c3SDavid McPaul 		return B_BAD_VALUE;
289105f452c3SDavid McPaul 
289205f452c3SDavid McPaul 	BMimeType aMimeType;
289305f452c3SDavid McPaul 
289405f452c3SDavid McPaul 	dormant_node_info nodes[30];
289505f452c3SDavid McPaul 	int32 count = 30;
289605f452c3SDavid McPaul 	int32 highestCapability = -1;
289705f452c3SDavid McPaul 	float capability;
289805f452c3SDavid McPaul 
289905f452c3SDavid McPaul 	media_node node;
290005f452c3SDavid McPaul 
290105f452c3SDavid McPaul 	// Get all dormant nodes using GetDormantNodes
29026f7f87a2SDavid McPaul 	if (GetDormantNodes(nodes, &count, NULL, NULL, NULL, requireNodeKinds | B_FILE_INTERFACE, 0) == B_OK) {
290305f452c3SDavid McPaul 		// Call SniffRefFor on each node that matches requireNodeKinds
290405f452c3SDavid McPaul 		for (int32 i=0;i<count;i++) {
29056f7f87a2SDavid McPaul 			if (InstantiateDormantNode(nodes[i], &node) == B_OK) {
290605f452c3SDavid McPaul 
29076f7f87a2SDavid McPaul 				if (SniffRefFor(node, file, &aMimeType, &capability) == B_OK) {
290805f452c3SDavid McPaul 					// find the first node that has 100% capability
290905f452c3SDavid McPaul 					TRACE("%s has a %f%% chance of playing file\n",nodes[i].name, capability * 100.0);
291005f452c3SDavid McPaul 					if (capability == 1.0) {
291105f452c3SDavid McPaul 						highestCapability = i;
291205f452c3SDavid McPaul 						break;
291305f452c3SDavid McPaul 					}
291405f452c3SDavid McPaul 				}
291505f452c3SDavid McPaul 				ReleaseNode(node);
291605f452c3SDavid McPaul 			}
291705f452c3SDavid McPaul 		}
291805f452c3SDavid McPaul 
291905f452c3SDavid McPaul 		if (highestCapability != -1) {
292005f452c3SDavid McPaul 			*_node = nodes[highestCapability];
292105f452c3SDavid McPaul 
2922332cc6bcSAxel Dörfler 			TRACE("BMediaRoster::SniffRef: found a node %s addon-id %" B_PRId32
2923332cc6bcSAxel Dörfler 				", flavor_id %" B_PRId32 "\n",
2924332cc6bcSAxel Dörfler 			nodes[highestCapability].name, nodes[highestCapability].addon,
2925332cc6bcSAxel Dörfler 				nodes[highestCapability].flavor_id);
292605f452c3SDavid McPaul 
292705f452c3SDavid McPaul 			if (mimeType != NULL) {
292805f452c3SDavid McPaul 				//*mimeType = aMimeType; -- need a copy constructor
292905f452c3SDavid McPaul 			}
293005f452c3SDavid McPaul 
293105f452c3SDavid McPaul 			return B_OK;
293205f452c3SDavid McPaul 		}
293305f452c3SDavid McPaul 
293405f452c3SDavid McPaul 	}
293505f452c3SDavid McPaul 
293652a38012Sejakowatz 	return B_ERROR;
293752a38012Sejakowatz }
293852a38012Sejakowatz 
293952a38012Sejakowatz 
294052a38012Sejakowatz status_t
294152a38012Sejakowatz BMediaRoster::GetDormantNodeForType(const BMimeType& type,
294234c72144SAxel Dörfler 	uint64 requireNodeKinds, dormant_node_info* _node)
294352a38012Sejakowatz {
294452a38012Sejakowatz 	UNIMPLEMENTED();
294552a38012Sejakowatz 	return B_ERROR;
294652a38012Sejakowatz }
294752a38012Sejakowatz 
294852a38012Sejakowatz 
294952a38012Sejakowatz status_t
295034c72144SAxel Dörfler BMediaRoster::GetReadFileFormatsFor(const dormant_node_info& node,
295134c72144SAxel Dörfler 	media_file_format* _readFormats, int32 readCount, int32* _readCount)
295252a38012Sejakowatz {
295352a38012Sejakowatz 	UNIMPLEMENTED();
295452a38012Sejakowatz 	return B_ERROR;
295552a38012Sejakowatz }
295652a38012Sejakowatz 
295752a38012Sejakowatz 
295852a38012Sejakowatz status_t
295934c72144SAxel Dörfler BMediaRoster::GetWriteFileFormatsFor(const dormant_node_info& node,
296034c72144SAxel Dörfler 	media_file_format* _write_formats, int32 writeCount, int32* _writeCount)
296152a38012Sejakowatz {
296252a38012Sejakowatz 	UNIMPLEMENTED();
296352a38012Sejakowatz 	return B_ERROR;
296452a38012Sejakowatz }
296552a38012Sejakowatz 
296652a38012Sejakowatz 
296752a38012Sejakowatz status_t
296834c72144SAxel Dörfler BMediaRoster::GetFormatFor(const media_output& output, media_format* _format,
296952a38012Sejakowatz 	uint32 flags)
297052a38012Sejakowatz {
29719bedd42cSbeveloper 	CALLED();
297234c72144SAxel Dörfler 	if (_format == NULL)
29739bedd42cSbeveloper 		return B_BAD_VALUE;
29749bedd42cSbeveloper 	if ((output.node.kind & B_BUFFER_PRODUCER) == 0)
29759bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
29769bedd42cSbeveloper 	if (IS_INVALID_SOURCE(output.source))
29779bedd42cSbeveloper 		return B_MEDIA_BAD_SOURCE;
29789bedd42cSbeveloper 
29799bedd42cSbeveloper 	producer_format_suggestion_requested_request request;
29809bedd42cSbeveloper 	producer_format_suggestion_requested_reply reply;
29819bedd42cSbeveloper 	status_t rv;
29829bedd42cSbeveloper 
29839bedd42cSbeveloper 	request.type = B_MEDIA_UNKNOWN_TYPE;
298434c72144SAxel Dörfler 	request.quality = 0; // TODO: what should this be?
29859bedd42cSbeveloper 
298634c72144SAxel Dörfler 	rv = QueryPort(output.source.port, PRODUCER_FORMAT_SUGGESTION_REQUESTED,
298734c72144SAxel Dörfler 		&request, sizeof(request), &reply, sizeof(reply));
29889bedd42cSbeveloper 	if (rv != B_OK)
29899bedd42cSbeveloper 		return rv;
29909bedd42cSbeveloper 
299134c72144SAxel Dörfler 	*_format = reply.format;
29929bedd42cSbeveloper 	return B_OK;
299352a38012Sejakowatz }
299452a38012Sejakowatz 
299552a38012Sejakowatz 
299652a38012Sejakowatz status_t
299734c72144SAxel Dörfler BMediaRoster::GetFormatFor(const media_input& input, media_format* _format,
299852a38012Sejakowatz 	uint32 flags)
299952a38012Sejakowatz {
30009bedd42cSbeveloper 	CALLED();
300134c72144SAxel Dörfler 	if (_format == NULL)
30029bedd42cSbeveloper 		return B_BAD_VALUE;
30039bedd42cSbeveloper 	if ((input.node.kind & B_BUFFER_CONSUMER) == 0)
30049bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
30059bedd42cSbeveloper 	if (IS_INVALID_DESTINATION(input.destination))
30069bedd42cSbeveloper 		return B_MEDIA_BAD_DESTINATION;
30079bedd42cSbeveloper 
30089bedd42cSbeveloper 	consumer_accept_format_request request;
30099bedd42cSbeveloper 	consumer_accept_format_reply reply;
30109bedd42cSbeveloper 	status_t rv;
30119bedd42cSbeveloper 
30129bedd42cSbeveloper 	request.dest = input.destination;
30139bedd42cSbeveloper 	memset(&request.format, 0, sizeof(request.format)); // wildcard
30149bedd42cSbeveloper 
301534c72144SAxel Dörfler 	rv = QueryPort(input.destination.port, CONSUMER_ACCEPT_FORMAT, &request,
301634c72144SAxel Dörfler 		sizeof(request), &reply, sizeof(reply));
30179bedd42cSbeveloper 	if (rv != B_OK)
30189bedd42cSbeveloper 		return rv;
30199bedd42cSbeveloper 
302034c72144SAxel Dörfler 	*_format = reply.format;
30219bedd42cSbeveloper 	return B_OK;
302252a38012Sejakowatz }
302352a38012Sejakowatz 
302452a38012Sejakowatz 
302552a38012Sejakowatz status_t
302634c72144SAxel Dörfler BMediaRoster::GetFormatFor(const media_node& node, media_format* _format,
302752a38012Sejakowatz 	float quality)
302852a38012Sejakowatz {
302952a38012Sejakowatz 	UNIMPLEMENTED();
303034c72144SAxel Dörfler 	if (_format == NULL)
30319bedd42cSbeveloper 		return B_BAD_VALUE;
30329bedd42cSbeveloper 	if (IS_INVALID_NODE(node))
30339bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
30349bedd42cSbeveloper 	if ((node.kind & (B_BUFFER_CONSUMER | B_BUFFER_PRODUCER)) == 0)
30359bedd42cSbeveloper 		return B_MEDIA_BAD_NODE;
30369bedd42cSbeveloper 
303752a38012Sejakowatz 	return B_ERROR;
303852a38012Sejakowatz }
303952a38012Sejakowatz 
304052a38012Sejakowatz 
304152a38012Sejakowatz ssize_t
304252a38012Sejakowatz BMediaRoster::GetNodeAttributesFor(const media_node& node,
304334c72144SAxel Dörfler 	media_node_attribute* _array, size_t maxCount)
304452a38012Sejakowatz {
304552a38012Sejakowatz 	UNIMPLEMENTED();
304652a38012Sejakowatz 	return B_ERROR;
304752a38012Sejakowatz }
304852a38012Sejakowatz 
304952a38012Sejakowatz 
305052a38012Sejakowatz media_node_id
305134c72144SAxel Dörfler BMediaRoster::NodeIDFor(port_id port)
305252a38012Sejakowatz {
30539e9417d2Sbeveloper 	CALLED();
30549e9417d2Sbeveloper 
30559e9417d2Sbeveloper 	server_node_id_for_request request;
30569e9417d2Sbeveloper 	server_node_id_for_reply reply;
30579e9417d2Sbeveloper 	status_t rv;
30589e9417d2Sbeveloper 
305934c72144SAxel Dörfler 	request.port = port;
30609e9417d2Sbeveloper 
306134c72144SAxel Dörfler 	rv = QueryServer(SERVER_NODE_ID_FOR, &request, sizeof(request), &reply,
306234c72144SAxel Dörfler 		sizeof(reply));
30639e9417d2Sbeveloper 	if (rv != B_OK) {
3064332cc6bcSAxel Dörfler 		ERROR("BMediaRoster::NodeIDFor: failed (error %#" B_PRIx32 ")\n", rv);
30659e9417d2Sbeveloper 		return -1;
30669e9417d2Sbeveloper 	}
30679e9417d2Sbeveloper 
30689dec2310SAxel Dörfler 	return reply.node_id;
306952a38012Sejakowatz }
307052a38012Sejakowatz 
307152a38012Sejakowatz 
307252a38012Sejakowatz status_t
307334c72144SAxel Dörfler BMediaRoster::GetInstancesFor(media_addon_id addon, int32 flavor,
307434c72144SAxel Dörfler 	media_node_id* _id, int32* _count)
307552a38012Sejakowatz {
307685dfab2bSbeveloper 	CALLED();
307734c72144SAxel Dörfler 	if (_id == NULL)
307885dfab2bSbeveloper 		return B_BAD_VALUE;
307934c72144SAxel Dörfler 	if (_count && *_count <= 0)
308085dfab2bSbeveloper 		return B_BAD_VALUE;
308185dfab2bSbeveloper 
308285dfab2bSbeveloper 	server_get_instances_for_request request;
308385dfab2bSbeveloper 	server_get_instances_for_reply reply;
308485dfab2bSbeveloper 	status_t rv;
308585dfab2bSbeveloper 
30869c3b4706SAxel Dörfler 	request.max_count = (_count ? *_count : 1);
30879c3b4706SAxel Dörfler 	request.add_on_id = addon;
30889c3b4706SAxel Dörfler 	request.flavor_id = flavor;
308985dfab2bSbeveloper 
309034c72144SAxel Dörfler 	rv = QueryServer(SERVER_GET_INSTANCES_FOR, &request, sizeof(request),
309134c72144SAxel Dörfler 		&reply, sizeof(reply));
309285dfab2bSbeveloper 	if (rv != B_OK) {
30935ac4fbd7Sbeveloper 		ERROR("BMediaRoster::GetLiveNodes failed\n");
309485dfab2bSbeveloper 		return rv;
309552a38012Sejakowatz 	}
309652a38012Sejakowatz 
309734c72144SAxel Dörfler 	if (_count)
309834c72144SAxel Dörfler 		*_count = reply.count;
309985dfab2bSbeveloper 	if (reply.count > 0)
310034c72144SAxel Dörfler 		memcpy(_id, reply.node_id, sizeof(media_node_id) * reply.count);
310185dfab2bSbeveloper 
310285dfab2bSbeveloper 	return B_OK;
310385dfab2bSbeveloper }
310452a38012Sejakowatz 
310552a38012Sejakowatz 
310652a38012Sejakowatz status_t
310734c72144SAxel Dörfler BMediaRoster::SetRealtimeFlags(uint32 enabled)
310852a38012Sejakowatz {
310952a38012Sejakowatz 	UNIMPLEMENTED();
311052a38012Sejakowatz 	return B_ERROR;
311152a38012Sejakowatz }
311252a38012Sejakowatz 
311352a38012Sejakowatz 
311452a38012Sejakowatz status_t
311534c72144SAxel Dörfler BMediaRoster::GetRealtimeFlags(uint32* _enabled)
311652a38012Sejakowatz {
311752a38012Sejakowatz 	UNIMPLEMENTED();
311852a38012Sejakowatz 	return B_ERROR;
311952a38012Sejakowatz }
312052a38012Sejakowatz 
312152a38012Sejakowatz 
312252a38012Sejakowatz ssize_t
312334c72144SAxel Dörfler BMediaRoster::AudioBufferSizeFor(int32 channelCount, uint32 sampleFormat,
312434c72144SAxel Dörfler 	float frameRate, bus_type busKind)
312552a38012Sejakowatz {
312634c72144SAxel Dörfler 	bigtime_t bufferDuration;
312734c72144SAxel Dörfler 	ssize_t bufferSize;
3128df6c2e83Sbeveloper 
3129df6c2e83Sbeveloper 	system_info info;
3130df6c2e83Sbeveloper 	get_system_info(&info);
3131df6c2e83Sbeveloper 
313234c72144SAxel Dörfler 	if (info.cpu_clock_speed > 2000000000)	// 2 GHz
313334c72144SAxel Dörfler 		bufferDuration = 2500;
3134df6c2e83Sbeveloper 	else if (info.cpu_clock_speed > 1000000000)
313534c72144SAxel Dörfler 		bufferDuration = 5000;
3136df6c2e83Sbeveloper 	else if (info.cpu_clock_speed > 600000000)
313734c72144SAxel Dörfler 		bufferDuration = 10000;
3138df6c2e83Sbeveloper 	else if (info.cpu_clock_speed > 200000000)
313934c72144SAxel Dörfler 		bufferDuration = 20000;
3140df6c2e83Sbeveloper 	else if (info.cpu_clock_speed > 100000000)
314134c72144SAxel Dörfler 		bufferDuration = 30000;
3142df6c2e83Sbeveloper 	else
314334c72144SAxel Dörfler 		bufferDuration = 50000;
3144df6c2e83Sbeveloper 
314534c72144SAxel Dörfler 	if ((busKind == B_ISA_BUS || busKind == B_PCMCIA_BUS)
314634c72144SAxel Dörfler 		&& bufferDuration < 25000)
314734c72144SAxel Dörfler 		bufferDuration = 25000;
3148df6c2e83Sbeveloper 
314934c72144SAxel Dörfler 	bufferSize = (sampleFormat & 0xf) * channelCount
315034c72144SAxel Dörfler 		* (ssize_t)((frameRate * bufferDuration) / 1000000.0);
3151df6c2e83Sbeveloper 
3152332cc6bcSAxel Dörfler 	printf("Suggested buffer duration %" B_PRId64 ", size %" B_PRIdSSIZE "\n",
3153332cc6bcSAxel Dörfler 		bufferDuration, bufferSize);
3154df6c2e83Sbeveloper 
315534c72144SAxel Dörfler 	return bufferSize;
315652a38012Sejakowatz }
315752a38012Sejakowatz 
315852a38012Sejakowatz 
315934c72144SAxel Dörfler /*!	Use MediaFlags to inquire about specific features of the Media Kit.
316034c72144SAxel Dörfler 	Returns < 0 for "not present", positive size for output data size.
316134c72144SAxel Dörfler 	0 means that the capability is present, but no data about it.
316234c72144SAxel Dörfler */
316352a38012Sejakowatz /*static*/ ssize_t
316434c72144SAxel Dörfler BMediaRoster::MediaFlags(media_flags cap, void* buffer, size_t maxSize)
316552a38012Sejakowatz {
316652a38012Sejakowatz 	UNIMPLEMENTED();
316752a38012Sejakowatz 	return 0;
316852a38012Sejakowatz }
316952a38012Sejakowatz 
317052a38012Sejakowatz 
317134c72144SAxel Dörfler //	#pragma mark - BLooper overrides
317234c72144SAxel Dörfler 
317334c72144SAxel Dörfler 
317434c72144SAxel Dörfler void
317552a38012Sejakowatz BMediaRoster::MessageReceived(BMessage* message)
317652a38012Sejakowatz {
3177cf4e2277Sbeveloper 	switch (message->what) {
3178cf4e2277Sbeveloper 		case 'PING':
3179cf4e2277Sbeveloper 		{
31806396865dSbeveloper 			// media_server plays ping-pong with the BMediaRosters
31816396865dSbeveloper 			// to detect dead teams. Normal communication uses ports.
31826396865dSbeveloper 			static BMessage pong('PONG');
31836396865dSbeveloper 			message->SendReply(&pong, static_cast<BHandler *>(NULL), 2000000);
31846396865dSbeveloper 			return;
31856396865dSbeveloper 		}
31866396865dSbeveloper 
3187cf4e2277Sbeveloper 		case NODE_FINAL_RELEASE:
3188cf4e2277Sbeveloper 		{
3189cf4e2277Sbeveloper 			// this function is called by a BMediaNode to delete
3190cf4e2277Sbeveloper 			// itself, as this needs to be done from another thread
3191cf4e2277Sbeveloper 			// context, it is done here.
319234c72144SAxel Dörfler 			// TODO: If a node is released using BMediaRoster::ReleaseNode()
319334c72144SAxel Dörfler 			// TODO: instead of using BMediaNode::Release() / BMediaNode::Acquire()
319434c72144SAxel Dörfler 			// TODO: fRefCount of the BMediaNode will not be correct.
3195cf4e2277Sbeveloper 
3196cf4e2277Sbeveloper 			BMediaNode *node;
3197cf4e2277Sbeveloper 			message->FindPointer("node", reinterpret_cast<void **>(&node));
3198cf4e2277Sbeveloper 
3199332cc6bcSAxel Dörfler 			TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE saving "
3200332cc6bcSAxel Dörfler 				"node %" B_PRId32 " configuration\n", node->ID());
320154187cc6Sbeveloper 			MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(node);
3202cf4e2277Sbeveloper 
3203332cc6bcSAxel Dörfler 			TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE releasing "
3204332cc6bcSAxel Dörfler 				"node %" B_PRId32 "\n", node->ID());
3205cf4e2277Sbeveloper 			node->DeleteHook(node); // we don't call Release(), see above!
3206cf4e2277Sbeveloper 			return;
3207cf4e2277Sbeveloper 		}
3208cf4e2277Sbeveloper 	}
32096396865dSbeveloper 	printf("BMediaRoster::MessageReceived: unknown message!\n");
32106396865dSbeveloper 	message->PrintToStream();
321152a38012Sejakowatz }
321252a38012Sejakowatz 
321334c72144SAxel Dörfler 
321434c72144SAxel Dörfler bool
321552a38012Sejakowatz BMediaRoster::QuitRequested()
321652a38012Sejakowatz {
321752a38012Sejakowatz 	UNIMPLEMENTED();
321852a38012Sejakowatz 	return true;
321952a38012Sejakowatz }
322052a38012Sejakowatz 
322134c72144SAxel Dörfler 
322234c72144SAxel Dörfler BHandler*
322334c72144SAxel Dörfler BMediaRoster::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier,
322434c72144SAxel Dörfler 	int32 form, const char* property)
322552a38012Sejakowatz {
3226286a3c91SJérôme Duval 	return BLooper::ResolveSpecifier(msg, index, specifier, form, property);
322752a38012Sejakowatz }
322852a38012Sejakowatz 
322952a38012Sejakowatz 
323034c72144SAxel Dörfler status_t
323152a38012Sejakowatz BMediaRoster::GetSupportedSuites(BMessage* data)
323252a38012Sejakowatz {
3233286a3c91SJérôme Duval 	return BLooper::GetSupportedSuites(data);
323452a38012Sejakowatz }
323552a38012Sejakowatz 
323652a38012Sejakowatz 
323752a38012Sejakowatz BMediaRoster::~BMediaRoster()
323852a38012Sejakowatz {
323952a38012Sejakowatz 	CALLED();
32406396865dSbeveloper 
3241f0a1eb2dSAxel Dörfler 	delete gTimeSourceObjectManager;
3242f0a1eb2dSAxel Dörfler 	delete gDormantNodeManager;
3243f0a1eb2dSAxel Dörfler 
32446396865dSbeveloper 	// unregister this application with the media server
32456396865dSbeveloper 	server_unregister_app_request request;
32466396865dSbeveloper 	server_unregister_app_reply reply;
32479dec2310SAxel Dörfler 	request.team = BPrivate::current_team();
324834c72144SAxel Dörfler 	QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply,
324934c72144SAxel Dörfler 		sizeof(reply));
32508b940bb4SStephan Aßmus 
32512f9ed888SAxel Dörfler 	BPrivate::SharedBufferList::Invalidate();
32522f9ed888SAxel Dörfler 
32538b940bb4SStephan Aßmus 	// Unset the global instance pointer, the destructor is also called
32548b940bb4SStephan Aßmus 	// if a client app calls Lock(); and Quit(); directly.
32559def3bf7SStephan Aßmus 	sDefaultInstance = NULL;
325652a38012Sejakowatz }
325752a38012Sejakowatz 
325852a38012Sejakowatz 
325934c72144SAxel Dörfler //	#pragma mark - private BMediaRoster
326034c72144SAxel Dörfler 
326152a38012Sejakowatz 
3262f0a1eb2dSAxel Dörfler //! Deprecated call.
326352a38012Sejakowatz status_t
326452a38012Sejakowatz BMediaRoster::SetOutputBuffersFor(const media_source& output,
326534c72144SAxel Dörfler 	BBufferGroup* group, bool willReclaim)
326652a38012Sejakowatz {
326752a38012Sejakowatz 	UNIMPLEMENTED();
32689e9417d2Sbeveloper 	debugger("BMediaRoster::SetOutputBuffersFor missing\n");
326952a38012Sejakowatz 	return B_ERROR;
327052a38012Sejakowatz }
327152a38012Sejakowatz 
327252a38012Sejakowatz 
3273f0a1eb2dSAxel Dörfler // FBC reserved virtuals
327452a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_0(void*) { return B_ERROR; }
327552a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_1(void*) { return B_ERROR; }
327652a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_2(void*) { return B_ERROR; }
327752a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_3(void*) { return B_ERROR; }
327852a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_4(void*) { return B_ERROR; }
327952a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_5(void*) { return B_ERROR; }
328052a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_6(void*) { return B_ERROR; }
328152a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_7(void*) { return B_ERROR; }
328252a38012Sejakowatz 
328352a38012Sejakowatz 
328434c72144SAxel Dörfler BMediaRoster::BMediaRoster()
32852f9ed888SAxel Dörfler 	:
32862f9ed888SAxel Dörfler 	BLooper("_BMediaRoster_", B_URGENT_DISPLAY_PRIORITY,
328734c72144SAxel Dörfler 		B_LOOPER_PORT_DEFAULT_CAPACITY)
328852a38012Sejakowatz {
328952a38012Sejakowatz 	CALLED();
32906396865dSbeveloper 
32916396865dSbeveloper 	// start the looper
32926396865dSbeveloper 	Run();
329352a38012Sejakowatz }
329452a38012Sejakowatz 
32956396865dSbeveloper 
32969def3bf7SStephan Aßmus // TODO: Looks like these can be safely removed:
329752a38012Sejakowatz /*static*/ status_t
329852a38012Sejakowatz BMediaRoster::ParseCommand(BMessage& reply)
329952a38012Sejakowatz {
330052a38012Sejakowatz 	UNIMPLEMENTED();
330152a38012Sejakowatz 	return B_ERROR;
330252a38012Sejakowatz }
330352a38012Sejakowatz 
330452a38012Sejakowatz 
330552a38012Sejakowatz status_t
330634c72144SAxel Dörfler BMediaRoster::GetDefaultInfo(media_node_id forDefault, BMessage& config)
330752a38012Sejakowatz {
330852a38012Sejakowatz 	UNIMPLEMENTED();
330952a38012Sejakowatz 	return B_ERROR;
331052a38012Sejakowatz }
331152a38012Sejakowatz 
331252a38012Sejakowatz 
331352a38012Sejakowatz status_t
331434c72144SAxel Dörfler BMediaRoster::SetRunningDefault(media_node_id forDefault,
331552a38012Sejakowatz 	const media_node& node)
331652a38012Sejakowatz {
331752a38012Sejakowatz 	UNIMPLEMENTED();
331852a38012Sejakowatz 	return B_ERROR;
331952a38012Sejakowatz }
332052a38012Sejakowatz 
332152a38012Sejakowatz 
33229def3bf7SStephan Aßmus // #pragma mark - static variables
332352a38012Sejakowatz 
33249def3bf7SStephan Aßmus 
33259def3bf7SStephan Aßmus BMediaRoster* BMediaRoster::sDefaultInstance = NULL;
3326