xref: /haiku/src/kits/media/MediaRoster.cpp (revision 5edd2016f885d0ff879a1224b48e9435d7ae376b)
1 /***********************************************************************
2  * AUTHOR: Marcus Overhagen
3  *   FILE: MediaRoster.cpp
4  *  DESCR:
5  ***********************************************************************/
6 #include <MediaRoster.h>
7 #include <Locker.h>
8 #include <Message.h>
9 #include <Messenger.h>
10 #include <StopWatch.h>
11 #include <OS.h>
12 #include <String.h>
13 #include <TimeSource.h>
14 #undef 	DEBUG
15 #define	DEBUG 3
16 #include "debug.h"
17 #include "PortPool.h"
18 #include "ServerInterface.h"
19 #include "DataExchange.h"
20 #include "DormantNodeManager.h"
21 #include "Notifications.h"
22 
23 using namespace BPrivate::media;
24 
25 namespace BPrivate { namespace media {
26 	extern team_id team;
27 }; };
28 
29 // the BMediaRoster destructor is private,
30 // but _DefaultDeleter is a friend class of
31 // the BMediaRoster an thus can delete it
32 class _DefaultDeleter
33 {
34 public:
35 	~_DefaultDeleter() { delete BMediaRoster::_sDefault; }
36 };
37 
38 _DefaultDeleter _deleter;
39 
40 namespace MediaKitPrivate
41 {
42 
43 
44 status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id = NULL, BString * out_input_name = NULL);
45 status_t SetNode(node_type type, const media_node *node, const dormant_node_info *info = NULL, const media_input *input = NULL);
46 
47 status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id, BString * out_input_name)
48 {
49 	if (out_node == NULL)
50 		return B_BAD_VALUE;
51 
52 	server_get_node_request request;
53 	server_get_node_reply reply;
54 	status_t rv;
55 
56 	request.type = type;
57 	rv = QueryServer(SERVER_GET_NODE, &request, sizeof(request), &reply, sizeof(reply));
58 	if (rv != B_OK)
59 		return rv;
60 
61 	*out_node = reply.node;
62 	if (out_input_id)
63 		*out_input_id = reply.input_id;
64 	if (out_input_name)
65 		*out_input_name = reply.input_name;
66 	return rv;
67 }
68 
69 status_t SetNode(node_type type, const media_node *node, const dormant_node_info *info, const media_input *input)
70 {
71 	server_set_node_request request;
72 	server_set_node_reply reply;
73 
74 	request.type = type;
75 	request.use_node = node ? true : false;
76 	if (node)
77 		request.node = *node;
78 	request.use_dni = info ? true : false;
79 	if (info)
80 		request.dni = *info;
81 	request.use_input = input ? true : false;
82 	if (input)
83 		request.input = *input;
84 
85 	return QueryServer(SERVER_SET_NODE, &request, sizeof(request), &reply, sizeof(reply));
86 }
87 
88 };
89 
90 /*************************************************************
91  * public BMediaRoster
92  *************************************************************/
93 
94 status_t
95 BMediaRoster::GetVideoInput(media_node * out_node)
96 {
97 	CALLED();
98 	return MediaKitPrivate::GetNode(VIDEO_INPUT, out_node);
99 }
100 
101 
102 status_t
103 BMediaRoster::GetAudioInput(media_node * out_node)
104 {
105 	CALLED();
106 	return MediaKitPrivate::GetNode(AUDIO_INPUT, out_node);
107 }
108 
109 
110 status_t
111 BMediaRoster::GetVideoOutput(media_node * out_node)
112 {
113 	CALLED();
114 	return MediaKitPrivate::GetNode(VIDEO_OUTPUT, out_node);
115 }
116 
117 
118 status_t
119 BMediaRoster::GetAudioMixer(media_node * out_node)
120 {
121 	CALLED();
122 	return MediaKitPrivate::GetNode(AUDIO_MIXER, out_node);
123 }
124 
125 
126 status_t
127 BMediaRoster::GetAudioOutput(media_node * out_node)
128 {
129 	CALLED();
130 	return MediaKitPrivate::GetNode(AUDIO_OUTPUT, out_node);
131 }
132 
133 
134 status_t
135 BMediaRoster::GetAudioOutput(media_node * out_node,
136 							 int32 * out_input_id,
137 							 BString * out_input_name)
138 {
139 	CALLED();
140 	return MediaKitPrivate::GetNode(AUDIO_OUTPUT_EX, out_node, out_input_id, out_input_name);
141 }
142 
143 
144 status_t
145 BMediaRoster::GetTimeSource(media_node * out_node)
146 {
147 	CALLED();
148 	return MediaKitPrivate::GetNode(TIME_SOURCE, out_node);
149 }
150 
151 
152 status_t
153 BMediaRoster::SetVideoInput(const media_node & producer)
154 {
155 	CALLED();
156 	return MediaKitPrivate::SetNode(VIDEO_INPUT, &producer);
157 }
158 
159 
160 status_t
161 BMediaRoster::SetVideoInput(const dormant_node_info & producer)
162 {
163 	CALLED();
164 	return MediaKitPrivate::SetNode(VIDEO_INPUT, NULL, &producer);
165 }
166 
167 
168 status_t
169 BMediaRoster::SetAudioInput(const media_node & producer)
170 {
171 	CALLED();
172 	return MediaKitPrivate::SetNode(AUDIO_INPUT, &producer);
173 }
174 
175 
176 status_t
177 BMediaRoster::SetAudioInput(const dormant_node_info & producer)
178 {
179 	CALLED();
180 	return MediaKitPrivate::SetNode(AUDIO_INPUT, NULL, &producer);
181 }
182 
183 
184 status_t
185 BMediaRoster::SetVideoOutput(const media_node & consumer)
186 {
187 	CALLED();
188 	return MediaKitPrivate::SetNode(VIDEO_OUTPUT, &consumer);
189 }
190 
191 
192 status_t
193 BMediaRoster::SetVideoOutput(const dormant_node_info & consumer)
194 {
195 	CALLED();
196 	return MediaKitPrivate::SetNode(VIDEO_OUTPUT, NULL, &consumer);
197 }
198 
199 
200 status_t
201 BMediaRoster::SetAudioOutput(const media_node & consumer)
202 {
203 	CALLED();
204 	return MediaKitPrivate::SetNode(AUDIO_OUTPUT, &consumer);
205 }
206 
207 
208 status_t
209 BMediaRoster::SetAudioOutput(const media_input & input_to_output)
210 {
211 	CALLED();
212 	return MediaKitPrivate::SetNode(AUDIO_OUTPUT, NULL, NULL, &input_to_output);
213 }
214 
215 
216 status_t
217 BMediaRoster::SetAudioOutput(const dormant_node_info & consumer)
218 {
219 	CALLED();
220 	return MediaKitPrivate::SetNode(AUDIO_OUTPUT, NULL, &consumer);
221 }
222 
223 
224 status_t
225 BMediaRoster::GetNodeFor(media_node_id node,
226 						 media_node * clone)
227 {
228 	UNIMPLEMENTED();
229 	return B_ERROR;
230 }
231 
232 
233 status_t
234 BMediaRoster::GetSystemTimeSource(media_node * clone)
235 {
236 	CALLED();
237 	return MediaKitPrivate::GetNode(SYSTEM_TIME_SOURCE, clone);
238 }
239 
240 
241 status_t
242 BMediaRoster::ReleaseNode(const media_node & node)
243 {
244 	UNIMPLEMENTED();
245 	return B_ERROR;
246 }
247 
248 
249 
250 BTimeSource *
251 BMediaRoster::MakeTimeSourceFor(const media_node & for_node)
252 {
253 	UNIMPLEMENTED();
254 	return 0;
255 }
256 
257 
258 status_t
259 BMediaRoster::Connect(const media_source & from,
260 					  const media_destination & to,
261 					  media_format * io_format,
262 					  media_output * out_output,
263 					  media_input * out_input)
264 {
265 	return BMediaRoster::Connect(from, to, io_format, out_output, out_input, 0);
266 }
267 
268 
269 status_t
270 BMediaRoster::Connect(const media_source & from,
271 					  const media_destination & to,
272 					  media_format * io_format,
273 					  media_output * out_output,
274 					  media_input * out_input,
275 					  uint32 in_flags,
276 					  void * _reserved)
277 {
278 	CALLED();
279 	if (io_format == NULL || out_output == NULL || out_input == NULL)
280 		return B_BAD_VALUE;
281 	if (from == media_source::null)
282 		return B_MEDIA_BAD_SOURCE;
283 	if (to == media_destination::null)
284 		return B_MEDIA_BAD_DESTINATION;
285 
286 	status_t rv;
287 	producer_format_proposal_request request1;
288 	producer_format_proposal_reply reply1;
289 
290 	// BBufferProducer::FormatProposal
291 	request1.output = from;
292 	request1.format = *io_format;
293 	rv = QueryPort(from.port, PRODUCER_FORMAT_PROPOSAL, &request1, sizeof(request1), &reply1, sizeof(reply1));
294 	if (rv != B_OK) {
295 		TRACE("BMediaRoster::Connect: aborted after BBufferProducer::FormatProposal, status = %#lx\n",rv);
296 		return rv;
297 	}
298 	// reply1.format now contains the format proposed by the producer
299 
300 	consumer_accept_format_request request2;
301 	consumer_accept_format_reply reply2;
302 
303 	// BBufferConsumer::AcceptFormat
304 	request2.dest = to;
305 	request2.format = reply1.format;
306 	rv = QueryPort(to.port, CONSUMER_ACCEPT_FORMAT, &request2, sizeof(request2), &reply2, sizeof(reply2));
307 	if (rv != B_OK) {
308 		TRACE("BMediaRoster::Connect: aborted after BBufferConsumer::AcceptFormat, status = %#lx\n",rv);
309 		return rv;
310 	}
311 	// reply2.format now contains the format accepted by the consumer
312 
313 	// BBufferProducer::PrepareToConnect
314 	producer_prepare_to_connect_request request3;
315 	producer_prepare_to_connect_reply reply3;
316 
317 	request3.source = from;
318 	request3.destination = to;
319 	request3.format = reply2.format;
320 	strcpy(request3.name, "XXX some default name"); // XXX fix this
321 	rv = QueryPort(from.port, PRODUCER_PREPARE_TO_CONNECT, &request3, sizeof(request3), &reply3, sizeof(reply3));
322 	if (rv != B_OK) {
323 		TRACE("BMediaRoster::Connect: aborted after BBufferProducer::PrepareToConnect, status = %#lx\n",rv);
324 		return rv;
325 	}
326 	// reply3.format is still our pretty media format
327 	// reply3.out_source the real source to be used for the connection
328 	// reply3.name the name BBufferConsumer::Connected will see in the outInput->name argument
329 
330 	// BBufferConsumer::Connected
331 	consumer_connected_request request4;
332 	consumer_connected_reply reply4;
333 	status_t con_status;
334 
335 	request4.producer = reply3.out_source;
336 	request4.where = to;
337 	request4.with_format = reply3.format;
338 	con_status = QueryPort(to.port, CONSUMER_CONNECTED, &request4, sizeof(request4), &reply4, sizeof(reply4));
339 	if (con_status != B_OK) {
340 		TRACE("BMediaRoster::Connect: aborting after BBufferConsumer::Connected, status = %#lx\n",con_status);
341 		// we do NOT return here!
342 	}
343 	// con_status contains the status code to be supplied to BBufferProducer::Connect's status argument
344 	// reply4.input contains the media_input that describes the connection from the consumer point of view
345 
346 	// BBufferProducer::Connect
347 	producer_connect_request request5;
348 	producer_connect_reply reply5;
349 
350 	request5.error = con_status;
351 	request5.source = reply3.out_source;
352 	request5.destination = reply4.input.destination;
353 	request5.format = reply3.format; // XXX reply4.input.format ???
354 	strcpy(request5.name, reply4.input.name);
355 	rv = QueryPort(reply4.input.node.port, PRODUCER_CONNECT, &request5, sizeof(request5), &reply5, sizeof(reply5));
356 	if (con_status != B_OK) {
357 		TRACE("BMediaRoster::Connect: aborted\n");
358 		return con_status;
359 	}
360 	if (rv != B_OK) {
361 		TRACE("BMediaRoster::Connect: aborted after BBufferProducer::Connect, status = %#lx\n",rv);
362 		return rv;
363 	}
364 	// reply5.name contains the name assigned to the connection by the producer
365 
366 	// find the output node
367 	// XXX isn't there a easier way?
368 	media_node sourcenode;
369 	GetNodeFor(NodeIDFor(from.port), &sourcenode);
370 	ReleaseNode(sourcenode);
371 
372 	// initilize connection info
373 	*io_format = reply3.format;
374 	*out_input = reply4.input;
375 	out_output->node = sourcenode;
376 	out_output->source = reply4.input.source;
377 	out_output->destination = reply4.input.destination;
378 	out_output->format = reply4.input.format;
379 	strcpy(out_output->name, reply5.name);
380 
381 	// the connection is now made
382 
383 
384 	// XXX register connection with server
385 
386 
387 	// XXX if (mute) BBufferProducer::EnableOutput(false)
388 
389 
390 	return B_OK;
391 };
392 
393 
394 status_t
395 BMediaRoster::Disconnect(media_node_id source_node,
396 						 const media_source & source,
397 						 media_node_id destination_node,
398 						 const media_destination & destination)
399 {
400 	UNIMPLEMENTED();
401 	return B_ERROR;
402 }
403 
404 
405 status_t
406 BMediaRoster::StartNode(const media_node & node,
407 						bigtime_t at_performance_time)
408 {
409 	CALLED();
410 	if (node.node == 0)
411 		return B_MEDIA_BAD_NODE;
412 
413 	xfer_node_start msg;
414 	msg.performance_time = at_performance_time;
415 
416 	return write_port(node.port, NODE_START, &msg, sizeof(msg));
417 }
418 
419 
420 status_t
421 BMediaRoster::StopNode(const media_node & node,
422 					   bigtime_t at_performance_time,
423 					   bool immediate)
424 {
425 	CALLED();
426 	if (node.node == 0)
427 		return B_MEDIA_BAD_NODE;
428 
429 	xfer_node_stop msg;
430 	msg.performance_time = at_performance_time;
431 	msg.immediate = immediate;
432 
433 	return write_port(node.port, NODE_STOP, &msg, sizeof(msg));
434 }
435 
436 
437 status_t
438 BMediaRoster::SeekNode(const media_node & node,
439 					   bigtime_t to_media_time,
440 					   bigtime_t at_performance_time)
441 {
442 	CALLED();
443 	if (node.node == 0)
444 		return B_MEDIA_BAD_NODE;
445 
446 	xfer_node_seek msg;
447 	msg.media_time = to_media_time;
448 	msg.performance_time = at_performance_time;
449 
450 	return write_port(node.port, NODE_SEEK, &msg, sizeof(msg));
451 }
452 
453 
454 status_t
455 BMediaRoster::StartTimeSource(const media_node & node,
456 							  bigtime_t at_real_time)
457 {
458 	CALLED();
459 	if (node.node == 0)
460 		return B_MEDIA_BAD_NODE;
461 	if ((node.kind & B_TIME_SOURCE) == 0)
462 		return B_MEDIA_BAD_NODE;
463 
464 	BTimeSource::time_source_op_info msg;
465 	msg.op = BTimeSource::B_TIMESOURCE_START;
466 	msg.real_time = at_real_time;
467 
468 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
469 }
470 
471 
472 status_t
473 BMediaRoster::StopTimeSource(const media_node & node,
474 							 bigtime_t at_real_time,
475 							 bool immediate)
476 {
477 	CALLED();
478 	if (node.node == 0)
479 		return B_MEDIA_BAD_NODE;
480 	if ((node.kind & B_TIME_SOURCE) == 0)
481 		return B_MEDIA_BAD_NODE;
482 
483 	BTimeSource::time_source_op_info msg;
484 	msg.op = immediate ? BTimeSource::B_TIMESOURCE_STOP_IMMEDIATELY : BTimeSource::B_TIMESOURCE_STOP;
485 	msg.real_time = at_real_time;
486 
487 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
488 }
489 
490 
491 status_t
492 BMediaRoster::SeekTimeSource(const media_node & node,
493 							 bigtime_t to_performance_time,
494 							 bigtime_t at_real_time)
495 {
496 	CALLED();
497 	if (node.node == 0)
498 		return B_MEDIA_BAD_NODE;
499 	if ((node.kind & B_TIME_SOURCE) == 0)
500 		return B_MEDIA_BAD_NODE;
501 
502 	BTimeSource::time_source_op_info msg;
503 	msg.op = BTimeSource::B_TIMESOURCE_SEEK;
504 	msg.real_time = at_real_time;
505 	msg.performance_time = to_performance_time;
506 
507 	return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg));
508 }
509 
510 
511 status_t
512 BMediaRoster::SyncToNode(const media_node & node,
513 						 bigtime_t at_time,
514 						 bigtime_t timeout)
515 {
516 	UNIMPLEMENTED();
517 	return B_ERROR;
518 }
519 
520 
521 status_t
522 BMediaRoster::SetRunModeNode(const media_node & node,
523 							 BMediaNode::run_mode mode)
524 {
525 	CALLED();
526 	if (node.node == 0)
527 		return B_MEDIA_BAD_NODE;
528 
529 	xfer_node_set_run_mode msg;
530 	msg.mode = mode;
531 
532 	return write_port(node.port, NODE_SET_RUN_MODE, &msg, sizeof(msg));
533 }
534 
535 
536 status_t
537 BMediaRoster::PrerollNode(const media_node & node)
538 {
539 	CALLED();
540 	if (node.node == 0)
541 		return B_MEDIA_BAD_NODE;
542 
543 	char dummy;
544 	return write_port(node.port, NODE_PREROLL, &dummy, sizeof(dummy));
545 }
546 
547 
548 status_t
549 BMediaRoster::RollNode(const media_node & node,
550 					   bigtime_t startPerformance,
551 					   bigtime_t stopPerformance,
552 					   bigtime_t atMediaTime)
553 {
554 	UNIMPLEMENTED();
555 	return B_ERROR;
556 }
557 
558 
559 status_t
560 BMediaRoster::SetProducerRunModeDelay(const media_node & node,
561 									  bigtime_t delay,
562 									  BMediaNode::run_mode mode)
563 {
564 	UNIMPLEMENTED();
565 	return B_ERROR;
566 }
567 
568 
569 status_t
570 BMediaRoster::SetProducerRate(const media_node & producer,
571 							  int32 numer,
572 							  int32 denom)
573 {
574 	CALLED();
575 	if (producer.node == 0)
576 		return B_MEDIA_BAD_NODE;
577 	if ((producer.kind & B_BUFFER_PRODUCER) == 0)
578 		return B_MEDIA_BAD_NODE;
579 
580 	xfer_producer_set_play_rate msg;
581 	xfer_producer_set_play_rate_reply reply;
582 	status_t rv;
583 	int32 code;
584 
585 	msg.numer = numer;
586 	msg.denom = denom;
587 	msg.reply_port = _PortPool->GetPort();
588 	rv = write_port(producer.node, PRODUCER_SET_PLAY_RATE, &msg, sizeof(msg));
589 	if (rv != B_OK) {
590 		_PortPool->PutPort(msg.reply_port);
591 		return rv;
592 	}
593 	rv = read_port(msg.reply_port, &code, &reply, sizeof(reply));
594 	_PortPool->PutPort(msg.reply_port);
595 	return (rv < B_OK) ? rv : reply.result;
596 }
597 
598 
599 
600 /* Nodes will have available inputs/outputs as long as they are capable */
601 /* of accepting more connections. The node may create an additional */
602 /* output or input as the currently available is taken into usage. */
603 status_t
604 BMediaRoster::GetLiveNodeInfo(const media_node & node,
605 							  live_node_info * out_live_info)
606 {
607 	UNIMPLEMENTED();
608 	return B_ERROR;
609 }
610 
611 
612 status_t
613 BMediaRoster::GetLiveNodes(live_node_info * out_live_nodes,
614 						   int32 * io_total_count,
615 						   const media_format * has_input,
616 						   const media_format * has_output,
617 						   const char * name,
618 						   uint64 node_kinds)
619 {
620 	UNIMPLEMENTED();
621 	return B_ERROR;
622 }
623 
624 
625 status_t
626 BMediaRoster::GetFreeInputsFor(const media_node & node,
627 							   media_input * out_free_inputs,
628 							   int32 buf_num_inputs,
629 							   int32 * out_total_count,
630 							   media_type filter_type)
631 {
632 	UNIMPLEMENTED();
633 	return B_ERROR;
634 }
635 
636 
637 status_t
638 BMediaRoster::GetConnectedInputsFor(const media_node & node,
639 									media_input * out_active_inputs,
640 									int32 buf_num_inputs,
641 									int32 * out_total_count)
642 {
643 	UNIMPLEMENTED();
644 	return B_ERROR;
645 }
646 
647 
648 status_t
649 BMediaRoster::GetAllInputsFor(const media_node & node,
650 							  media_input * out_inputs,
651 							  int32 buf_num_inputs,
652 							  int32 * out_total_count)
653 {
654 	CALLED();
655 	if (node.node == 0 || (node.kind & B_BUFFER_CONSUMER) == 0)
656 		return B_MEDIA_BAD_NODE;
657 	if (out_inputs == NULL || out_total_count == NULL)
658 		return B_BAD_VALUE;
659 
660 	status_t rv;
661 	status_t rv2;
662 	port_id port;
663 	int32 code;
664 	int32 cookie;
665 
666 	port = _PortPool->GetPort();
667 	*out_total_count = 0;
668 	cookie = 0;
669 	rv = B_OK;
670 	for (int32 i = 0; i < buf_num_inputs; i++) {
671 		xfer_consumer_get_next_input msg;
672 		xfer_consumer_get_next_input_reply reply;
673 		msg.cookie = cookie;
674 		msg.reply_port = port;
675 		rv = write_port(node.port, CONSUMER_GET_NEXT_INPUT, &msg, sizeof(msg));
676 		if (rv != B_OK)
677 			break;
678 		rv = read_port(msg.reply_port, &code, &reply, sizeof(reply));
679 		if (rv < B_OK || reply.result != B_OK)
680 			break;
681 		*out_total_count += 1;
682 		out_inputs[i] = reply.input;
683 		cookie = reply.cookie;
684 	}
685 	_PortPool->PutPort(port);
686 
687 	xfer_consumer_dispose_input_cookie msg2;
688 	msg2.cookie = cookie;
689 	rv2 = write_port(node.port, CONSUMER_DISPOSE_INPUT_COOKIE, &msg2, sizeof(msg2));
690 
691 	return (rv < B_OK) ? rv : rv2;
692 }
693 
694 
695 status_t
696 BMediaRoster::GetFreeOutputsFor(const media_node & node,
697 								media_output * out_free_outputs,
698 								int32 buf_num_outputs,
699 								int32 * out_total_count,
700 								media_type filter_type)
701 {
702 	UNIMPLEMENTED();
703 	return B_ERROR;
704 }
705 
706 
707 status_t
708 BMediaRoster::GetConnectedOutputsFor(const media_node & node,
709 									 media_output * out_active_outputs,
710 									 int32 buf_num_outputs,
711 									 int32 * out_total_count)
712 {
713 	UNIMPLEMENTED();
714 	return B_ERROR;
715 }
716 
717 
718 status_t
719 BMediaRoster::GetAllOutputsFor(const media_node & node,
720 							   media_output * out_outputs,
721 							   int32 buf_num_outputs,
722 							   int32 * out_total_count)
723 {
724 	CALLED();
725 	if (node.node == 0 || (node.kind & B_BUFFER_PRODUCER) == 0)
726 		return B_MEDIA_BAD_NODE;
727 	if (out_outputs == NULL || out_total_count == NULL)
728 		return B_BAD_VALUE;
729 
730 	status_t rv;
731 	status_t rv2;
732 	port_id port;
733 	int32 code;
734 	int32 cookie;
735 
736 	port = _PortPool->GetPort();
737 	*out_total_count = 0;
738 	cookie = 0;
739 	rv = B_OK;
740 	for (int32 i = 0; i < buf_num_outputs; i++) {
741 		xfer_producer_get_next_output msg;
742 		xfer_producer_get_next_output_reply reply;
743 		msg.cookie = cookie;
744 		msg.reply_port = port;
745 		rv = write_port(node.port, PRODUCER_GET_NEXT_OUTPUT, &msg, sizeof(msg));
746 		if (rv != B_OK)
747 			break;
748 		rv = read_port(msg.reply_port, &code, &reply, sizeof(reply));
749 		if (rv < B_OK || reply.result != B_OK)
750 			break;
751 		*out_total_count += 1;
752 		out_outputs[i] = reply.output;
753 		cookie = reply.cookie;
754 	}
755 	_PortPool->PutPort(port);
756 
757 	xfer_producer_dispose_output_cookie msg2;
758 	msg2.cookie = cookie;
759 	rv2 = write_port(node.port, PRODUCER_DISPOSE_OUTPUT_COOKIE, &msg2, sizeof(msg2));
760 
761 	return (rv < B_OK) ? rv : rv2;
762 }
763 
764 
765 status_t
766 BMediaRoster::StartWatching(const BMessenger & where)
767 {
768 	CALLED();
769 	if (!where.IsValid()) {
770 		TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
771 		return B_BAD_VALUE;
772 	}
773 	return BPrivate::media::notifications::Register(where, media_node::null, B_MEDIA_WILDCARD);
774 }
775 
776 
777 status_t
778 BMediaRoster::StartWatching(const BMessenger & where,
779 							int32 notificationType)
780 {
781 	CALLED();
782 	if (!where.IsValid()) {
783 		TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
784 		return B_BAD_VALUE;
785 	}
786 	if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) {
787 		TRACE("BMediaRoster::StartWatching: notificationType invalid!\n");
788 		return B_BAD_VALUE;
789 	}
790 	return BPrivate::media::notifications::Register(where, media_node::null, notificationType);
791 }
792 
793 
794 status_t
795 BMediaRoster::StartWatching(const BMessenger & where,
796 							const media_node & node,
797 							int32 notificationType)
798 {
799 	CALLED();
800 	if (!where.IsValid()) {
801 		TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
802 		return B_BAD_VALUE;
803 	}
804 	if (node.node == 0) {
805 		TRACE("BMediaRoster::StartWatching: node invalid!\n");
806 		return B_MEDIA_BAD_NODE;
807 	}
808 	if (false == BPrivate::media::notifications::IsValidNotificationRequest(true, notificationType)) {
809 		TRACE("BMediaRoster::StartWatching: notificationType invalid!\n");
810 		return B_BAD_VALUE;
811 	}
812 	return BPrivate::media::notifications::Register(where, node, notificationType);
813 }
814 
815 
816 status_t
817 BMediaRoster::StopWatching(const BMessenger & where)
818 {
819 	CALLED();
820 	// messenger may already be invalid, so we don't check this
821 	return BPrivate::media::notifications::Unregister(where, media_node::null, B_MEDIA_WILDCARD);
822 }
823 
824 
825 status_t
826 BMediaRoster::StopWatching(const BMessenger & where,
827 						   int32 notificationType)
828 {
829 	CALLED();
830 	// messenger may already be invalid, so we don't check this
831 	if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) {
832 		TRACE("BMediaRoster::StopWatching: notificationType invalid!\n");
833 		return B_BAD_VALUE;
834 	}
835 	return BPrivate::media::notifications::Unregister(where, media_node::null, notificationType);
836 }
837 
838 
839 status_t
840 BMediaRoster::StopWatching(const BMessenger & where,
841 						   const media_node & node,
842 						   int32 notificationType)
843 {
844 	CALLED();
845 	// messenger may already be invalid, so we don't check this
846 	if (node.node == 0) {
847 		TRACE("BMediaRoster::StopWatching: node invalid!\n");
848 		return B_MEDIA_BAD_NODE;
849 	}
850 	if (false == BPrivate::media::notifications::IsValidNotificationRequest(true, notificationType)) {
851 		TRACE("BMediaRoster::StopWatching: notificationType invalid!\n");
852 		return B_BAD_VALUE;
853 	}
854 	return BPrivate::media::notifications::Unregister(where, node, notificationType);
855 }
856 
857 
858 status_t
859 BMediaRoster::RegisterNode(BMediaNode * node)
860 {
861 	CALLED();
862 	if (node == NULL)
863 		return B_BAD_VALUE;
864 
865 	xfer_node_registered msg;
866 	msg.node_id = 1;
867 
868 	return node->HandleMessage(NODE_REGISTERED,&msg,sizeof(msg));
869 }
870 
871 
872 status_t
873 BMediaRoster::UnregisterNode(BMediaNode * node)
874 {
875 	UNIMPLEMENTED();
876 	return B_ERROR;
877 }
878 
879 
880 //	thread safe for multiple calls to Roster()
881 /* static */ BMediaRoster *
882 BMediaRoster::Roster(status_t* out_error)
883 {
884 	CALLED();
885 	static BLocker locker("BMediaRoster::Roster locker");
886 	locker.Lock();
887 	if (_sDefault == NULL) {
888 		_sDefault = new BMediaRoster();
889 		if (out_error != NULL)
890 			*out_error = B_OK;
891 	} else {
892 		if (out_error != NULL)
893 			*out_error = B_OK;
894 	}
895 	locker.Unlock();
896 	return _sDefault;
897 }
898 
899 
900 //	won't create it if there isn't one
901 //	not thread safe if you call Roster() at the same time
902 /* static */ BMediaRoster *
903 BMediaRoster::CurrentRoster()
904 {
905 	CALLED();
906 	return _sDefault;
907 }
908 
909 
910 status_t
911 BMediaRoster::SetTimeSourceFor(media_node_id node,
912 							   media_node_id time_source)
913 {
914 	UNIMPLEMENTED();
915 	return B_ERROR;
916 }
917 
918 
919 status_t
920 BMediaRoster::GetParameterWebFor(const media_node & node,
921 								 BParameterWeb ** out_web)
922 {
923 	UNIMPLEMENTED();
924 	return B_ERROR;
925 }
926 
927 
928 status_t
929 BMediaRoster::StartControlPanel(const media_node & node,
930 								BMessenger * out_messenger)
931 {
932 	UNIMPLEMENTED();
933 	return B_ERROR;
934 }
935 
936 
937 status_t
938 BMediaRoster::GetDormantNodes(dormant_node_info * out_info,
939 							  int32 * io_count,
940 							  const media_format * has_input /* = NULL */,
941 							  const media_format * has_output /* = NULL */,
942 							  const char * name /* = NULL */,
943 							  uint64 require_kinds /* = NULL */,
944 							  uint64 deny_kinds /* = NULL */)
945 {
946 	CALLED();
947 	if (out_info == NULL)
948 		return B_BAD_VALUE;
949 	if (io_count == NULL)
950 		return B_BAD_VALUE;
951 	if (*io_count <= 0)
952 		return B_BAD_VALUE;
953 
954 	xfer_server_get_dormant_nodes msg;
955 	port_id port;
956 	status_t rv;
957 
958 	port = find_port("media_server port");
959 	if (port <= B_OK)
960 		return B_ERROR;
961 
962 	msg.maxcount = *io_count;
963 	msg.has_input = (bool) has_input;
964 	if (has_input)
965 		msg.inputformat = *has_input; // XXX we should not make a flat copy of media_format
966 	msg.has_output = (bool) has_output;
967 	if (has_output)
968 		msg.outputformat = *has_output;; // XXX we should not make a flat copy of media_format
969 	msg.has_name = (bool) name;
970 	if (name) {
971 		int len = min_c(strlen(name),sizeof(msg.name) - 1);
972 		memcpy(msg.name,name,len);
973 		msg.name[len] = 0;
974 	}
975 	msg.require_kinds = require_kinds;
976 	msg.deny_kinds = deny_kinds;
977 	msg.reply_port = _PortPool->GetPort();
978 
979 	rv = write_port(port, SERVER_GET_DORMANT_NODES, &msg, sizeof(msg));
980 	if (rv != B_OK) {
981 		_PortPool->PutPort(msg.reply_port);
982 		return rv;
983 	}
984 
985 	xfer_server_get_dormant_nodes_reply reply;
986 	int32 code;
987 
988 	rv = read_port(msg.reply_port, &code, &reply, sizeof(reply));
989 	if (rv < B_OK) {
990 		_PortPool->PutPort(msg.reply_port);
991 		return rv;
992 	}
993 
994 	*io_count = reply.count;
995 
996 	if (*io_count > 0) {
997 		rv = read_port(msg.reply_port, &code, out_info, *io_count * sizeof(dormant_node_info));
998 		if (rv < B_OK)
999 			reply.result = rv;
1000 	}
1001 	_PortPool->PutPort(msg.reply_port);
1002 
1003 	return reply.result;
1004 }
1005 
1006 
1007 status_t
1008 BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info,
1009 									 media_node * out_node,
1010 									 uint32 flags /* currently B_FLAVOR_IS_GLOBAL or B_FLAVOR_IS_LOCAL */ )
1011 {
1012 	CALLED();
1013 	if ((flags & (B_FLAVOR_IS_GLOBAL | B_FLAVOR_IS_LOCAL)) == 0) {
1014 		printf("Error: BMediaRoster::InstantiateDormantNode called without flags\n");
1015 		return B_BAD_VALUE;
1016 	}
1017 	if (out_node == 0)
1018 		return B_BAD_VALUE;
1019 
1020 	// XXX we should not trust the values passed in by the user,
1021 	// XXX and ask the server to determine where to insta
1022 
1023 
1024 // XXX SOMETHING IS VERY WRONG HERE
1025 //	if ((in_info.flavor_flags & B_FLAVOR_IS_GLOBAL) == 0 && (flags & B_FLAVOR_IS_LOCAL)) {
1026 	if (flags & B_FLAVOR_IS_LOCAL) {
1027 		return InstantiateDormantNode(in_info,out_node);
1028 	}
1029 
1030 // XXX SOMETHING IS VERY WRONG HERE
1031 //	if ((in_info.flavor_flags & B_FLAVOR_IS_GLOBAL) || (flags & B_FLAVOR_IS_GLOBAL)) {
1032 	if (flags & B_FLAVOR_IS_GLOBAL) {
1033 		// forward this request into the media_addon_server,
1034 		// which in turn will call InstantiateDormantNode()
1035 		// to create it there localy
1036 		addonserver_instantiate_dormant_node_request request;
1037 		addonserver_instantiate_dormant_node_reply reply;
1038 		status_t rv;
1039 
1040 		request.info = in_info;
1041 		rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request, sizeof(request), &reply, sizeof(reply));
1042 		if (rv == B_OK) {
1043 			*out_node = reply.node;
1044 		}
1045 		return rv;
1046 	}
1047 
1048 // XXX SOMETHING IS VERY WRONG HERE
1049 	printf("Error: BMediaRoster::InstantiateDormantNode addon_id %d, flavor_id %d, flags %#08lx\n", (int)in_info.addon, (int)in_info.flavor_id, flags);
1050 
1051 	return B_ERROR;
1052 }
1053 
1054 
1055 status_t
1056 BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info,
1057 									 media_node * out_node)
1058 {
1059 	CALLED();
1060 
1061 	// to instantiate a dormant node in the current address space, we need to
1062 	// either load the add-on from file and create a new BMediaAddOn class, or
1063 	// reuse the cached BMediaAddOn from a previous call
1064 	// call BMediaAddOn::InstantiateNodeFor()
1065 	// and cache the BMediaAddOn after that for later reuse.
1066 	// BeOS R5 does not seem to delete it when the application quits
1067 	// if B_FLAVOR_IS_GLOBAL, we need to use the BMediaAddOn object that
1068 	// resides in the media_addon_server
1069 
1070 	// RegisterNode() is called automatically for nodes instantiated from add-ons
1071 
1072 	//XXX TEST!
1073 	BMediaAddOn *addon;
1074 	BMediaNode *node;
1075 	BMessage config;
1076 	status_t out_error;
1077 	status_t rv;
1078 	addon = _DormantNodeManager->GetAddon(in_info.addon);
1079 	if (!addon) {
1080 		printf("BMediaRoster::InstantiateDormantNode: GetAddon failed\n");
1081 		return B_ERROR;
1082 	}
1083 	flavor_info temp;
1084 	temp.internal_id = in_info.flavor_id;
1085 	node = addon->InstantiateNodeFor(&temp, &config, &out_error);
1086 	if (!node) {
1087 		printf("BMediaRoster::InstantiateDormantNode: InstantiateNodeFor failed\n");
1088 		_DormantNodeManager->PutAddon(in_info.addon);
1089 		return B_ERROR;
1090 	}
1091 	rv = RegisterNode(node);
1092 	if (rv != B_OK) {
1093 		printf("BMediaRoster::InstantiateDormantNode: RegisterNode failed\n");
1094 		delete node;
1095 		_DormantNodeManager->PutAddon(in_info.addon);
1096 		return B_ERROR;
1097 	}
1098 
1099 	// XXX we must remember in_info.addon and call
1100 	// XXX _DormantNodeManager->PutAddon when the
1101 	// XXX node is unregistered
1102 
1103 	*out_node = node->Node();
1104 	return B_OK;
1105 }
1106 
1107 
1108 status_t
1109 BMediaRoster::GetDormantNodeFor(const media_node & node,
1110 								dormant_node_info * out_info)
1111 {
1112 	UNIMPLEMENTED();
1113 
1114 	return B_ERROR;
1115 }
1116 
1117 
1118 status_t
1119 BMediaRoster::GetDormantFlavorInfoFor(const dormant_node_info & in_dormant,
1120 									  dormant_flavor_info * out_flavor)
1121 {
1122 	CALLED();
1123 
1124 	xfer_server_get_dormant_flavor_info msg;
1125 	xfer_server_get_dormant_flavor_info_reply *reply;
1126 	port_id port;
1127 	status_t rv;
1128 	int32 code;
1129 
1130 	port = find_port("media_server port");
1131 	if (port <= B_OK)
1132 		return B_ERROR;
1133 
1134 	reply = (xfer_server_get_dormant_flavor_info_reply *) malloc(16000);
1135 	if (reply == 0)
1136 		return B_ERROR;
1137 
1138 	msg.addon 		= in_dormant.addon;
1139 	msg.flavor_id 	= in_dormant.flavor_id;
1140 	msg.reply_port 	= _PortPool->GetPort();
1141 	rv = write_port(port, SERVER_GET_DORMANT_FLAVOR_INFO, &msg, sizeof(msg));
1142 	if (rv != B_OK) {
1143 		free(reply);
1144 		_PortPool->PutPort(msg.reply_port);
1145 		return rv;
1146 	}
1147 	rv = read_port(msg.reply_port, &code, reply, 16000);
1148 	_PortPool->PutPort(msg.reply_port);
1149 
1150 	if (rv < B_OK) {
1151 		free(reply);
1152 		return rv;
1153 	}
1154 
1155 	if (reply->result == B_OK)
1156 		rv = out_flavor->Unflatten(reply->dfi_type, &reply->dfi, reply->dfi_size);
1157 	else
1158 		rv = reply->result;
1159 
1160 	free(reply);
1161 	return rv;
1162 }
1163 
1164 
1165 status_t
1166 BMediaRoster::GetLatencyFor(const media_node & producer,
1167 							bigtime_t * out_latency)
1168 {
1169 	UNIMPLEMENTED();
1170 	*out_latency = 0;
1171 	return B_ERROR;
1172 }
1173 
1174 
1175 status_t
1176 BMediaRoster::GetInitialLatencyFor(const media_node & producer,
1177 								   bigtime_t * out_latency,
1178 								   uint32 * out_flags)
1179 {
1180 	UNIMPLEMENTED();
1181 	*out_latency = 0;
1182 	*out_flags = 0;
1183 	return B_ERROR;
1184 }
1185 
1186 
1187 status_t
1188 BMediaRoster::GetStartLatencyFor(const media_node & time_source,
1189 								 bigtime_t * out_latency)
1190 {
1191 	UNIMPLEMENTED();
1192 	*out_latency = 0;
1193 	return B_ERROR;
1194 }
1195 
1196 
1197 status_t
1198 BMediaRoster::GetFileFormatsFor(const media_node & file_interface,
1199 								media_file_format * out_formats,
1200 								int32 * io_num_infos)
1201 {
1202 	UNIMPLEMENTED();
1203 	return B_ERROR;
1204 }
1205 
1206 
1207 status_t
1208 BMediaRoster::SetRefFor(const media_node & file_interface,
1209 						const entry_ref & file,
1210 						bool create_and_truncate,
1211 						bigtime_t * out_length)	/* if create is false */
1212 {
1213 	UNIMPLEMENTED();
1214 	return B_ERROR;
1215 }
1216 
1217 
1218 status_t
1219 BMediaRoster::GetRefFor(const media_node & node,
1220 						entry_ref * out_file,
1221 						BMimeType * mime_type)
1222 {
1223 	UNIMPLEMENTED();
1224 	return B_ERROR;
1225 }
1226 
1227 
1228 status_t
1229 BMediaRoster::SniffRefFor(const media_node & file_interface,
1230 						  const entry_ref & file,
1231 						  BMimeType * mime_type,
1232 						  float * out_capability)
1233 {
1234 	UNIMPLEMENTED();
1235 	return B_ERROR;
1236 }
1237 
1238 
1239 /* This is the generic "here's a file, now can someone please play it" interface */
1240 status_t
1241 BMediaRoster::SniffRef(const entry_ref & file,
1242 					   uint64 require_node_kinds,		/* if you need an EntityInterface or BufferConsumer or something */
1243 					   dormant_node_info * out_node,
1244 					   BMimeType * mime_type)
1245 {
1246 	UNIMPLEMENTED();
1247 	return B_ERROR;
1248 }
1249 
1250 
1251 status_t
1252 BMediaRoster::GetDormantNodeForType(const BMimeType & type,
1253 									uint64 require_node_kinds,
1254 									dormant_node_info * out_node)
1255 {
1256 	UNIMPLEMENTED();
1257 	return B_ERROR;
1258 }
1259 
1260 
1261 status_t
1262 BMediaRoster::GetReadFileFormatsFor(const dormant_node_info & in_node,
1263 									media_file_format * out_read_formats,
1264 									int32 in_read_count,
1265 									int32 * out_read_count)
1266 {
1267 	UNIMPLEMENTED();
1268 	return B_ERROR;
1269 }
1270 
1271 
1272 status_t
1273 BMediaRoster::GetWriteFileFormatsFor(const dormant_node_info & in_node,
1274 									 media_file_format * out_write_formats,
1275 									 int32 in_write_count,
1276 									 int32 * out_write_count)
1277 {
1278 	UNIMPLEMENTED();
1279 	return B_ERROR;
1280 }
1281 
1282 
1283 status_t
1284 BMediaRoster::GetFormatFor(const media_output & output,
1285 						   media_format * io_format,
1286 						   uint32 flags)
1287 {
1288 	UNIMPLEMENTED();
1289 	return B_ERROR;
1290 }
1291 
1292 
1293 status_t
1294 BMediaRoster::GetFormatFor(const media_input & input,
1295 						   media_format * io_format,
1296 						   uint32 flags)
1297 {
1298 	UNIMPLEMENTED();
1299 	return B_ERROR;
1300 }
1301 
1302 
1303 status_t
1304 BMediaRoster::GetFormatFor(const media_node & node,
1305 						   media_format * io_format,
1306 						   float quality)
1307 {
1308 	UNIMPLEMENTED();
1309 	return B_ERROR;
1310 }
1311 
1312 
1313 ssize_t
1314 BMediaRoster::GetNodeAttributesFor(const media_node & node,
1315 								   media_node_attribute * outArray,
1316 								   size_t inMaxCount)
1317 {
1318 	UNIMPLEMENTED();
1319 	return B_ERROR;
1320 }
1321 
1322 
1323 media_node_id
1324 BMediaRoster::NodeIDFor(port_id source_or_destination_port)
1325 {
1326 	UNIMPLEMENTED();
1327 	return B_ERROR;
1328 }
1329 
1330 
1331 status_t
1332 BMediaRoster::GetInstancesFor(media_addon_id addon,
1333 							  int32 flavor,
1334 							  media_node_id * out_id,
1335 							  int32 * io_count)
1336 {
1337 	UNIMPLEMENTED();
1338 	return B_ERROR;
1339 }
1340 
1341 
1342 
1343 status_t
1344 BMediaRoster::SetRealtimeFlags(uint32 in_enabled)
1345 {
1346 	UNIMPLEMENTED();
1347 	return B_ERROR;
1348 }
1349 
1350 
1351 status_t
1352 BMediaRoster::GetRealtimeFlags(uint32 * out_enabled)
1353 {
1354 	UNIMPLEMENTED();
1355 	return B_ERROR;
1356 }
1357 
1358 
1359 ssize_t
1360 BMediaRoster::AudioBufferSizeFor(int32 channel_count,
1361 								 uint32 sample_format,
1362 								 float frame_rate,
1363 								 bus_type bus_kind)
1364 {
1365 	UNIMPLEMENTED();
1366 	return 4096;
1367 }
1368 
1369 
1370 /* Use MediaFlags to inquire about specific features of the Media Kit. */
1371 /* Returns < 0 for "not present", positive size for output data size. */
1372 /* 0 means that the capability is present, but no data about it. */
1373 /* static */ ssize_t
1374 BMediaRoster::MediaFlags(media_flags cap,
1375 						 void * buf,
1376 						 size_t maxSize)
1377 {
1378 	UNIMPLEMENTED();
1379 	return 0;
1380 }
1381 
1382 
1383 
1384 /* BLooper overrides */
1385 /* virtual */ void
1386 BMediaRoster::MessageReceived(BMessage * message)
1387 {
1388 	UNIMPLEMENTED();
1389 }
1390 
1391 /* virtual */ bool
1392 BMediaRoster::QuitRequested()
1393 {
1394 	UNIMPLEMENTED();
1395 	return true;
1396 }
1397 
1398 /* virtual */ BHandler *
1399 BMediaRoster::ResolveSpecifier(BMessage *msg,
1400 				 int32 index,
1401 				 BMessage *specifier,
1402 				 int32 form,
1403 				 const char *property)
1404 {
1405 	UNIMPLEMENTED();
1406 	return 0;
1407 }
1408 
1409 
1410 /* virtual */ status_t
1411 BMediaRoster::GetSupportedSuites(BMessage *data)
1412 {
1413 	UNIMPLEMENTED();
1414 	return B_ERROR;
1415 }
1416 
1417 
1418 BMediaRoster::~BMediaRoster()
1419 {
1420 	CALLED();
1421 	BMessage msg(MEDIA_SERVER_UNREGISTER_APP);
1422 	BMessage reply;
1423 	msg.AddInt32("team",team);
1424 	QueryServer(&msg, &reply);
1425 }
1426 
1427 
1428 /*************************************************************
1429  * private BMediaRoster
1430  *************************************************************/
1431 
1432 // deprecated call
1433 status_t
1434 BMediaRoster::SetOutputBuffersFor(const media_source & output,
1435 								  BBufferGroup * group,
1436 								  bool will_reclaim )
1437 {
1438 	UNIMPLEMENTED();
1439 	return B_ERROR;
1440 }
1441 
1442 
1443 /* FBC stuffing (Mmmh, Stuffing!) */
1444 status_t BMediaRoster::_Reserved_MediaRoster_0(void *) { return B_ERROR; }
1445 status_t BMediaRoster::_Reserved_MediaRoster_1(void *) { return B_ERROR; }
1446 status_t BMediaRoster::_Reserved_MediaRoster_2(void *) { return B_ERROR; }
1447 status_t BMediaRoster::_Reserved_MediaRoster_3(void *) { return B_ERROR; }
1448 status_t BMediaRoster::_Reserved_MediaRoster_4(void *) { return B_ERROR; }
1449 status_t BMediaRoster::_Reserved_MediaRoster_5(void *) { return B_ERROR; }
1450 status_t BMediaRoster::_Reserved_MediaRoster_6(void *) { return B_ERROR; }
1451 status_t BMediaRoster::_Reserved_MediaRoster_7(void *) { return B_ERROR; }
1452 
1453 
1454 BMediaRoster::BMediaRoster() :
1455 	BLooper("BMediaRoster looper",B_NORMAL_PRIORITY,B_LOOPER_PORT_DEFAULT_CAPACITY)
1456 {
1457 	CALLED();
1458 	BMessage msg(MEDIA_SERVER_REGISTER_APP);
1459 	BMessage reply;
1460 	msg.AddInt32("team",team);
1461 	QueryServer(&msg,&reply);
1462 }
1463 
1464 /* static */ status_t
1465 BMediaRoster::ParseCommand(BMessage & reply)
1466 {
1467 	UNIMPLEMENTED();
1468 	return B_ERROR;
1469 }
1470 
1471 
1472 
1473 status_t
1474 BMediaRoster::GetDefaultInfo(media_node_id for_default,
1475 							 BMessage & out_config)
1476 {
1477 	UNIMPLEMENTED();
1478 	return B_ERROR;
1479 }
1480 
1481 
1482 
1483 status_t
1484 BMediaRoster::SetRunningDefault(media_node_id for_default,
1485 								const media_node & node)
1486 {
1487 	UNIMPLEMENTED();
1488 	return B_ERROR;
1489 }
1490 
1491 
1492 /*************************************************************
1493  * static BMediaRoster variables
1494  *************************************************************/
1495 
1496 bool BMediaRoster::_isMediaServer;
1497 port_id BMediaRoster::_mReplyPort;
1498 int32 BMediaRoster::_mReplyPortRes;
1499 int32 BMediaRoster::_mReplyPortUnavailCount;
1500 BMediaRoster * BMediaRoster::_sDefault = NULL;
1501 
1502