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