152a38012Sejakowatz /*********************************************************************** 252a38012Sejakowatz * AUTHOR: Marcus Overhagen 352a38012Sejakowatz * FILE: MediaRoster.cpp 452a38012Sejakowatz * DESCR: 552a38012Sejakowatz ***********************************************************************/ 652a38012Sejakowatz #include <MediaRoster.h> 752a38012Sejakowatz #include <Locker.h> 852a38012Sejakowatz #include <Message.h> 952a38012Sejakowatz #include <Messenger.h> 1052a38012Sejakowatz #include <StopWatch.h> 1152a38012Sejakowatz #include <OS.h> 1252a38012Sejakowatz #include <String.h> 1352a38012Sejakowatz #include <TimeSource.h> 1452a38012Sejakowatz #include "debug.h" 1576669a29Sbeveloper #include "TList.h" 1652a38012Sejakowatz #include "PortPool.h" 170a483e72SIngo Weinhold #include "ServerInterface.h" 18f4925104Sbeveloper #include "DataExchange.h" 1916b7eea4Sbeveloper #include "DormantNodeManager.h" 20f4925104Sbeveloper #include "Notifications.h" 21835140c8Sbeveloper #include "TimeSourceObjectManager.h" 2252a38012Sejakowatz 23f4925104Sbeveloper namespace BPrivate { namespace media { 24f4925104Sbeveloper extern team_id team; 253620737cSbeveloper } } // BPrivate::media 263620737cSbeveloper 273620737cSbeveloper using namespace BPrivate::media; 2852a38012Sejakowatz 2952a38012Sejakowatz // the BMediaRoster destructor is private, 3052a38012Sejakowatz // but _DefaultDeleter is a friend class of 3152a38012Sejakowatz // the BMediaRoster an thus can delete it 3252a38012Sejakowatz class _DefaultDeleter 3352a38012Sejakowatz { 3452a38012Sejakowatz public: 356396865dSbeveloper ~_DefaultDeleter() 366396865dSbeveloper { 376396865dSbeveloper if (BMediaRoster::_sDefault) { 386396865dSbeveloper BMediaRoster::_sDefault->Lock(); 396396865dSbeveloper BMediaRoster::_sDefault->Quit(); 406396865dSbeveloper } 416396865dSbeveloper } 426396865dSbeveloper } _deleter; 4352a38012Sejakowatz 443620737cSbeveloper namespace BPrivate { namespace media { namespace mediaroster { 4552a38012Sejakowatz 4652a38012Sejakowatz status_t GetNode(node_type type, media_node * out_node, int32 * out_input_id = NULL, BString * out_input_name = NULL); 4752a38012Sejakowatz status_t SetNode(node_type type, const media_node *node, const dormant_node_info *info = NULL, const media_input *input = NULL); 4876669a29Sbeveloper status_t GetAllOutputs(const media_node & node, List<media_output> *list); 4976669a29Sbeveloper status_t GetAllInputs(const media_node & node, List<media_input> *list); 5076669a29Sbeveloper status_t PublishOutputs(const media_node & node, List<media_output> *list); 5176669a29Sbeveloper status_t PublishInputs(const media_node & node, List<media_input> *list); 5252a38012Sejakowatz 533620737cSbeveloper status_t 543620737cSbeveloper GetNode(node_type type, media_node * out_node, int32 * out_input_id, BString * out_input_name) 5552a38012Sejakowatz { 5652a38012Sejakowatz if (out_node == NULL) 5752a38012Sejakowatz return B_BAD_VALUE; 5852a38012Sejakowatz 598c6a6096Sbeveloper server_get_node_request request; 608c6a6096Sbeveloper server_get_node_reply reply; 6152a38012Sejakowatz status_t rv; 6252a38012Sejakowatz 638c6a6096Sbeveloper request.type = type; 649e9417d2Sbeveloper request.team = team; 658c6a6096Sbeveloper rv = QueryServer(SERVER_GET_NODE, &request, sizeof(request), &reply, sizeof(reply)); 668c6a6096Sbeveloper if (rv != B_OK) 678c6a6096Sbeveloper return rv; 6852a38012Sejakowatz 6952a38012Sejakowatz *out_node = reply.node; 7052a38012Sejakowatz if (out_input_id) 7152a38012Sejakowatz *out_input_id = reply.input_id; 7252a38012Sejakowatz if (out_input_name) 7352a38012Sejakowatz *out_input_name = reply.input_name; 748c6a6096Sbeveloper return rv; 7552a38012Sejakowatz } 7652a38012Sejakowatz 773620737cSbeveloper status_t 783620737cSbeveloper SetNode(node_type type, const media_node *node, const dormant_node_info *info, const media_input *input) 7952a38012Sejakowatz { 808c6a6096Sbeveloper server_set_node_request request; 818c6a6096Sbeveloper server_set_node_reply reply; 8252a38012Sejakowatz 838c6a6096Sbeveloper request.type = type; 848c6a6096Sbeveloper request.use_node = node ? true : false; 8552a38012Sejakowatz if (node) 868c6a6096Sbeveloper request.node = *node; 878c6a6096Sbeveloper request.use_dni = info ? true : false; 8852a38012Sejakowatz if (info) 898c6a6096Sbeveloper request.dni = *info; 908c6a6096Sbeveloper request.use_input = input ? true : false; 9152a38012Sejakowatz if (input) 928c6a6096Sbeveloper request.input = *input; 9352a38012Sejakowatz 948c6a6096Sbeveloper return QueryServer(SERVER_SET_NODE, &request, sizeof(request), &reply, sizeof(reply)); 9552a38012Sejakowatz } 9652a38012Sejakowatz 973620737cSbeveloper status_t 9876669a29Sbeveloper GetAllOutputs(const media_node & node, List<media_output> *list) 993620737cSbeveloper { 1003620737cSbeveloper int32 cookie; 1013620737cSbeveloper status_t rv; 1023620737cSbeveloper status_t result; 1033620737cSbeveloper 1043620737cSbeveloper result = B_OK; 1053620737cSbeveloper cookie = 0; 10676669a29Sbeveloper list->MakeEmpty(); 1073620737cSbeveloper for (;;) { 1083620737cSbeveloper producer_get_next_output_request request; 1093620737cSbeveloper producer_get_next_output_reply reply; 1103620737cSbeveloper request.cookie = cookie; 1110caff283Sbeveloper rv = QueryPort(node.port, PRODUCER_GET_NEXT_OUTPUT, &request, sizeof(request), &reply, sizeof(reply)); 1123620737cSbeveloper if (rv != B_OK) 1133620737cSbeveloper break; 1143620737cSbeveloper cookie = reply.cookie; 11576669a29Sbeveloper if (!list->Insert(reply.output)) { 11676669a29Sbeveloper FATAL("GetAllOutputs: list->Insert failed\n"); 1173620737cSbeveloper result = B_ERROR; 1183620737cSbeveloper } 1193620737cSbeveloper } 1203620737cSbeveloper 1213620737cSbeveloper producer_dispose_output_cookie_request request; 1223620737cSbeveloper producer_dispose_output_cookie_reply reply; 1230caff283Sbeveloper QueryPort(node.port, PRODUCER_DISPOSE_OUTPUT_COOKIE, &request, sizeof(request), &reply, sizeof(reply)); 1243620737cSbeveloper 1253620737cSbeveloper return result; 1263620737cSbeveloper } 1273620737cSbeveloper 1283620737cSbeveloper status_t 12976669a29Sbeveloper GetAllInputs(const media_node & node, List<media_input> *list) 1303620737cSbeveloper { 1313620737cSbeveloper int32 cookie; 1323620737cSbeveloper status_t rv; 1333620737cSbeveloper status_t result; 1343620737cSbeveloper 1353620737cSbeveloper result = B_OK; 1363620737cSbeveloper cookie = 0; 13776669a29Sbeveloper list->MakeEmpty(); 1383620737cSbeveloper for (;;) { 1393620737cSbeveloper consumer_get_next_input_request request; 1403620737cSbeveloper consumer_get_next_input_reply reply; 1413620737cSbeveloper request.cookie = cookie; 1420caff283Sbeveloper rv = QueryPort(node.port, CONSUMER_GET_NEXT_INPUT, &request, sizeof(request), &reply, sizeof(reply)); 1433620737cSbeveloper if (rv != B_OK) 1443620737cSbeveloper break; 1453620737cSbeveloper cookie = reply.cookie; 14676669a29Sbeveloper if (!list->Insert(reply.input)) { 14776669a29Sbeveloper FATAL("GetAllInputs: list->Insert failed\n"); 1483620737cSbeveloper result = B_ERROR; 1493620737cSbeveloper } 1503620737cSbeveloper } 1513620737cSbeveloper 1523620737cSbeveloper consumer_dispose_input_cookie_request request; 1533620737cSbeveloper consumer_dispose_input_cookie_reply reply; 1540caff283Sbeveloper QueryPort(node.port, CONSUMER_DISPOSE_INPUT_COOKIE, &request, sizeof(request), &reply, sizeof(reply)); 1553620737cSbeveloper 1563620737cSbeveloper return result; 1573620737cSbeveloper } 1583620737cSbeveloper 1593620737cSbeveloper status_t 16076669a29Sbeveloper PublishOutputs(const media_node & node, List<media_output> *list) 1613620737cSbeveloper { 1623620737cSbeveloper server_publish_outputs_request request; 1633620737cSbeveloper server_publish_outputs_reply reply; 1643620737cSbeveloper media_output *output; 1653620737cSbeveloper media_output *outputs; 1663620737cSbeveloper int32 count; 167a7b41a96Sbeveloper status_t rv; 1683620737cSbeveloper 16976669a29Sbeveloper count = list->CountItems(); 1703620737cSbeveloper TRACE("PublishOutputs: publishing %ld\n", count); 1713620737cSbeveloper 1723620737cSbeveloper request.node = node; 1733620737cSbeveloper request.count = count; 1743620737cSbeveloper if (count > MAX_OUTPUTS) { 1753620737cSbeveloper void *start_addr; 1763620737cSbeveloper size_t size; 1773620737cSbeveloper size = ((count * sizeof(media_output)) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); 1783620737cSbeveloper request.area = create_area("publish outputs", &start_addr, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); 1793620737cSbeveloper if (request.area < B_OK) { 180353b9f6bSbeveloper FATAL("PublishOutputs: failed to create area, %#lx\n", request.area); 1813620737cSbeveloper return (status_t)request.area; 1823620737cSbeveloper } 1833620737cSbeveloper outputs = static_cast<media_output *>(start_addr); 1843620737cSbeveloper } else { 1853620737cSbeveloper request.area = -1; 1863620737cSbeveloper outputs = request.outputs; 1873620737cSbeveloper } 18876669a29Sbeveloper TRACE("PublishOutputs: area %ld\n", request.area); 1893620737cSbeveloper 19076669a29Sbeveloper int i; 19176669a29Sbeveloper for (i = 0, list->Rewind(); list->GetNext(&output); i++) { 19276669a29Sbeveloper ASSERT(i < count); 1933620737cSbeveloper outputs[i] = *output; 1943620737cSbeveloper } 1953620737cSbeveloper 196a7b41a96Sbeveloper rv = QueryServer(SERVER_PUBLISH_OUTPUTS, &request, sizeof(request), &reply, sizeof(reply)); 197a7b41a96Sbeveloper 198a7b41a96Sbeveloper if (request.area != -1) 199a7b41a96Sbeveloper delete_area(request.area); 200a7b41a96Sbeveloper 201a7b41a96Sbeveloper return rv; 2023620737cSbeveloper } 2033620737cSbeveloper 2043620737cSbeveloper status_t 20576669a29Sbeveloper PublishInputs(const media_node & node, List<media_input> *list) 2063620737cSbeveloper { 2073620737cSbeveloper server_publish_inputs_request request; 2083620737cSbeveloper server_publish_inputs_reply reply; 2093620737cSbeveloper media_input *input; 2103620737cSbeveloper media_input *inputs; 2113620737cSbeveloper int32 count; 212a7b41a96Sbeveloper status_t rv; 2133620737cSbeveloper 21476669a29Sbeveloper count = list->CountItems(); 2153620737cSbeveloper TRACE("PublishInputs: publishing %ld\n", count); 2163620737cSbeveloper 2173620737cSbeveloper request.node = node; 2183620737cSbeveloper request.count = count; 2193620737cSbeveloper if (count > MAX_INPUTS) { 2203620737cSbeveloper void *start_addr; 2213620737cSbeveloper size_t size; 2223620737cSbeveloper size = ((count * sizeof(media_input)) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); 2233620737cSbeveloper request.area = create_area("publish inputs", &start_addr, B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); 2243620737cSbeveloper if (request.area < B_OK) { 225353b9f6bSbeveloper FATAL("PublishInputs: failed to create area, %#lx\n", request.area); 2263620737cSbeveloper return (status_t)request.area; 2273620737cSbeveloper } 2283620737cSbeveloper inputs = static_cast<media_input *>(start_addr); 2293620737cSbeveloper } else { 2303620737cSbeveloper request.area = -1; 2313620737cSbeveloper inputs = request.inputs; 2323620737cSbeveloper } 23376669a29Sbeveloper TRACE("PublishInputs: area %ld\n", request.area); 2343620737cSbeveloper 23576669a29Sbeveloper int i; 23676669a29Sbeveloper for (i = 0, list->Rewind(); list->GetNext(&input); i++) { 23776669a29Sbeveloper ASSERT(i < count); 2383620737cSbeveloper inputs[i] = *input; 2393620737cSbeveloper } 2403620737cSbeveloper 241a7b41a96Sbeveloper rv = QueryServer(SERVER_PUBLISH_INPUTS, &request, sizeof(request), &reply, sizeof(reply)); 242a7b41a96Sbeveloper 243a7b41a96Sbeveloper if (request.area != -1) 244a7b41a96Sbeveloper delete_area(request.area); 245a7b41a96Sbeveloper 246a7b41a96Sbeveloper return rv; 2473620737cSbeveloper } 2483620737cSbeveloper 2493620737cSbeveloper } } } // namespace BPrivate::media::mediaroster 2503620737cSbeveloper 2513620737cSbeveloper using namespace BPrivate::media::mediaroster; 25252a38012Sejakowatz 25352a38012Sejakowatz /************************************************************* 25452a38012Sejakowatz * public BMediaRoster 25552a38012Sejakowatz *************************************************************/ 25652a38012Sejakowatz 25752a38012Sejakowatz status_t 25852a38012Sejakowatz BMediaRoster::GetVideoInput(media_node * out_node) 25952a38012Sejakowatz { 26052a38012Sejakowatz CALLED(); 2613620737cSbeveloper return GetNode(VIDEO_INPUT, out_node); 26252a38012Sejakowatz } 26352a38012Sejakowatz 26452a38012Sejakowatz 26552a38012Sejakowatz status_t 26652a38012Sejakowatz BMediaRoster::GetAudioInput(media_node * out_node) 26752a38012Sejakowatz { 26852a38012Sejakowatz CALLED(); 2693620737cSbeveloper return GetNode(AUDIO_INPUT, out_node); 27052a38012Sejakowatz } 27152a38012Sejakowatz 27252a38012Sejakowatz 27352a38012Sejakowatz status_t 27452a38012Sejakowatz BMediaRoster::GetVideoOutput(media_node * out_node) 27552a38012Sejakowatz { 27652a38012Sejakowatz CALLED(); 2773620737cSbeveloper return GetNode(VIDEO_OUTPUT, out_node); 27852a38012Sejakowatz } 27952a38012Sejakowatz 28052a38012Sejakowatz 28152a38012Sejakowatz status_t 28252a38012Sejakowatz BMediaRoster::GetAudioMixer(media_node * out_node) 28352a38012Sejakowatz { 28452a38012Sejakowatz CALLED(); 2853620737cSbeveloper return GetNode(AUDIO_MIXER, out_node); 28652a38012Sejakowatz } 28752a38012Sejakowatz 28852a38012Sejakowatz 28952a38012Sejakowatz status_t 29052a38012Sejakowatz BMediaRoster::GetAudioOutput(media_node * out_node) 29152a38012Sejakowatz { 29252a38012Sejakowatz CALLED(); 2933620737cSbeveloper return GetNode(AUDIO_OUTPUT, out_node); 29452a38012Sejakowatz } 29552a38012Sejakowatz 29652a38012Sejakowatz 29752a38012Sejakowatz status_t 29852a38012Sejakowatz BMediaRoster::GetAudioOutput(media_node * out_node, 29952a38012Sejakowatz int32 * out_input_id, 30052a38012Sejakowatz BString * out_input_name) 30152a38012Sejakowatz { 30252a38012Sejakowatz CALLED(); 3033620737cSbeveloper return GetNode(AUDIO_OUTPUT_EX, out_node, out_input_id, out_input_name); 30452a38012Sejakowatz } 30552a38012Sejakowatz 30652a38012Sejakowatz 30752a38012Sejakowatz status_t 30852a38012Sejakowatz BMediaRoster::GetTimeSource(media_node * out_node) 30952a38012Sejakowatz { 31052a38012Sejakowatz CALLED(); 3113620737cSbeveloper return GetNode(TIME_SOURCE, out_node); 31252a38012Sejakowatz } 31352a38012Sejakowatz 31452a38012Sejakowatz 31552a38012Sejakowatz status_t 31652a38012Sejakowatz BMediaRoster::SetVideoInput(const media_node & producer) 31752a38012Sejakowatz { 31852a38012Sejakowatz CALLED(); 3193620737cSbeveloper return SetNode(VIDEO_INPUT, &producer); 32052a38012Sejakowatz } 32152a38012Sejakowatz 32252a38012Sejakowatz 32352a38012Sejakowatz status_t 32452a38012Sejakowatz BMediaRoster::SetVideoInput(const dormant_node_info & producer) 32552a38012Sejakowatz { 32652a38012Sejakowatz CALLED(); 3273620737cSbeveloper return SetNode(VIDEO_INPUT, NULL, &producer); 32852a38012Sejakowatz } 32952a38012Sejakowatz 33052a38012Sejakowatz 33152a38012Sejakowatz status_t 33252a38012Sejakowatz BMediaRoster::SetAudioInput(const media_node & producer) 33352a38012Sejakowatz { 33452a38012Sejakowatz CALLED(); 3353620737cSbeveloper return SetNode(AUDIO_INPUT, &producer); 33652a38012Sejakowatz } 33752a38012Sejakowatz 33852a38012Sejakowatz 33952a38012Sejakowatz status_t 34052a38012Sejakowatz BMediaRoster::SetAudioInput(const dormant_node_info & producer) 34152a38012Sejakowatz { 34252a38012Sejakowatz CALLED(); 3433620737cSbeveloper return SetNode(AUDIO_INPUT, NULL, &producer); 34452a38012Sejakowatz } 34552a38012Sejakowatz 34652a38012Sejakowatz 34752a38012Sejakowatz status_t 34852a38012Sejakowatz BMediaRoster::SetVideoOutput(const media_node & consumer) 34952a38012Sejakowatz { 35052a38012Sejakowatz CALLED(); 3513620737cSbeveloper return SetNode(VIDEO_OUTPUT, &consumer); 35252a38012Sejakowatz } 35352a38012Sejakowatz 35452a38012Sejakowatz 35552a38012Sejakowatz status_t 35652a38012Sejakowatz BMediaRoster::SetVideoOutput(const dormant_node_info & consumer) 35752a38012Sejakowatz { 35852a38012Sejakowatz CALLED(); 3593620737cSbeveloper return SetNode(VIDEO_OUTPUT, NULL, &consumer); 36052a38012Sejakowatz } 36152a38012Sejakowatz 36252a38012Sejakowatz 36352a38012Sejakowatz status_t 36452a38012Sejakowatz BMediaRoster::SetAudioOutput(const media_node & consumer) 36552a38012Sejakowatz { 36652a38012Sejakowatz CALLED(); 3673620737cSbeveloper return SetNode(AUDIO_OUTPUT, &consumer); 36852a38012Sejakowatz } 36952a38012Sejakowatz 37052a38012Sejakowatz 37152a38012Sejakowatz status_t 37252a38012Sejakowatz BMediaRoster::SetAudioOutput(const media_input & input_to_output) 37352a38012Sejakowatz { 37452a38012Sejakowatz CALLED(); 3753620737cSbeveloper return SetNode(AUDIO_OUTPUT, NULL, NULL, &input_to_output); 37652a38012Sejakowatz } 37752a38012Sejakowatz 37852a38012Sejakowatz 37952a38012Sejakowatz status_t 38052a38012Sejakowatz BMediaRoster::SetAudioOutput(const dormant_node_info & consumer) 38152a38012Sejakowatz { 38252a38012Sejakowatz CALLED(); 3833620737cSbeveloper return SetNode(AUDIO_OUTPUT, NULL, &consumer); 38452a38012Sejakowatz } 38552a38012Sejakowatz 38652a38012Sejakowatz 38752a38012Sejakowatz status_t 38852a38012Sejakowatz BMediaRoster::GetNodeFor(media_node_id node, 38952a38012Sejakowatz media_node * clone) 39052a38012Sejakowatz { 3919e9417d2Sbeveloper CALLED(); 3929e9417d2Sbeveloper if (clone == NULL) 3939e9417d2Sbeveloper return B_BAD_VALUE; 3949e9417d2Sbeveloper if (node <= 0) 3959e9417d2Sbeveloper return B_MEDIA_BAD_NODE; 3969e9417d2Sbeveloper 3979e9417d2Sbeveloper server_get_node_for_request request; 3989e9417d2Sbeveloper server_get_node_for_reply reply; 3999e9417d2Sbeveloper status_t rv; 4009e9417d2Sbeveloper 4019e9417d2Sbeveloper request.nodeid = node; 4029e9417d2Sbeveloper request.team = team; 4039e9417d2Sbeveloper 4049e9417d2Sbeveloper rv = QueryServer(SERVER_GET_NODE_FOR, &request, sizeof(request), &reply, sizeof(reply)); 4059e9417d2Sbeveloper if (rv != B_OK) 4069e9417d2Sbeveloper return rv; 4079e9417d2Sbeveloper 4089e9417d2Sbeveloper *clone = reply.clone; 4099e9417d2Sbeveloper return B_OK; 41052a38012Sejakowatz } 41152a38012Sejakowatz 41252a38012Sejakowatz 41352a38012Sejakowatz status_t 41452a38012Sejakowatz BMediaRoster::GetSystemTimeSource(media_node * clone) 41552a38012Sejakowatz { 41652a38012Sejakowatz CALLED(); 4173620737cSbeveloper return GetNode(SYSTEM_TIME_SOURCE, clone); 41852a38012Sejakowatz } 41952a38012Sejakowatz 42052a38012Sejakowatz 42152a38012Sejakowatz status_t 42252a38012Sejakowatz BMediaRoster::ReleaseNode(const media_node & node) 42352a38012Sejakowatz { 4249e9417d2Sbeveloper CALLED(); 4259e9417d2Sbeveloper if (node.node <= 0) 4269e9417d2Sbeveloper return B_MEDIA_BAD_NODE; 42752a38012Sejakowatz 4289e9417d2Sbeveloper server_release_node_request request; 4299e9417d2Sbeveloper server_release_node_reply reply; 4309e9417d2Sbeveloper 4319e9417d2Sbeveloper request.node = node; 4329e9417d2Sbeveloper request.team = team; 4339e9417d2Sbeveloper 4349e9417d2Sbeveloper return QueryServer(SERVER_RELEASE_NODE, &request, sizeof(request), &reply, sizeof(reply)); 4359e9417d2Sbeveloper } 43652a38012Sejakowatz 43752a38012Sejakowatz BTimeSource * 43852a38012Sejakowatz BMediaRoster::MakeTimeSourceFor(const media_node & for_node) 43952a38012Sejakowatz { 440835140c8Sbeveloper CALLED(); 441287f7492Sbeveloper 442*0e21b167Sbeveloper BTimeSource *source; 443287f7492Sbeveloper 444*0e21b167Sbeveloper // printf("BMediaRoster::MakeTimeSourceFor enter, node %ld, port %ld, kind %#lx\n", for_node.node, for_node.port, for_node.kind); 445287f7492Sbeveloper 446*0e21b167Sbeveloper if (0 == (for_node.kind & B_TIME_SOURCE)) { 447*0e21b167Sbeveloper FATAL("BMediaRoster::MakeTimeSourceFor, node %ld is not a timesource!\n", for_node.node); 448*0e21b167Sbeveloper // XXX It appears that Cortex calls this function on every node, and expects 449*0e21b167Sbeveloper // XXX to be returned a system time source if the for_node is not a timesource 450*0e21b167Sbeveloper media_node clone; 451*0e21b167Sbeveloper GetSystemTimeSource(&clone); 452*0e21b167Sbeveloper source = _TimeSourceObjectManager->GetTimeSource(clone); 453*0e21b167Sbeveloper ReleaseNode(clone); 454*0e21b167Sbeveloper } else { 455*0e21b167Sbeveloper source = _TimeSourceObjectManager->GetTimeSource(for_node); 456*0e21b167Sbeveloper } 457*0e21b167Sbeveloper 458*0e21b167Sbeveloper // printf("BMediaRoster::MakeTimeSourceFor leave, node %ld, port %ld, kind %#lx\n", source->Node().node, source->Node().port, source->Node().kind); 459287f7492Sbeveloper 460835140c8Sbeveloper return source; 46152a38012Sejakowatz } 46252a38012Sejakowatz 46352a38012Sejakowatz 46452a38012Sejakowatz status_t 46552a38012Sejakowatz BMediaRoster::Connect(const media_source & from, 46652a38012Sejakowatz const media_destination & to, 46752a38012Sejakowatz media_format * io_format, 46852a38012Sejakowatz media_output * out_output, 46952a38012Sejakowatz media_input * out_input) 47052a38012Sejakowatz { 471eae26d3dSbeveloper return BMediaRoster::Connect(from, to, io_format, out_output, out_input, 0); 472eae26d3dSbeveloper } 473eae26d3dSbeveloper 474eae26d3dSbeveloper 475eae26d3dSbeveloper status_t 476eae26d3dSbeveloper BMediaRoster::Connect(const media_source & from, 477eae26d3dSbeveloper const media_destination & to, 478eae26d3dSbeveloper media_format * io_format, 479eae26d3dSbeveloper media_output * out_output, 480eae26d3dSbeveloper media_input * out_input, 481eae26d3dSbeveloper uint32 in_flags, 482eae26d3dSbeveloper void * _reserved) 483eae26d3dSbeveloper { 48452a38012Sejakowatz CALLED(); 48552a38012Sejakowatz if (io_format == NULL || out_output == NULL || out_input == NULL) 48652a38012Sejakowatz return B_BAD_VALUE; 4879e9417d2Sbeveloper if (from == media_source::null) { 488353b9f6bSbeveloper FATAL("BMediaRoster::Connect: media_source invalid\n"); 48952a38012Sejakowatz return B_MEDIA_BAD_SOURCE; 4909e9417d2Sbeveloper } 4919e9417d2Sbeveloper if (to == media_destination::null) { 492353b9f6bSbeveloper FATAL("BMediaRoster::Connect: media_destination invalid\n"); 49352a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 4949e9417d2Sbeveloper } 49552a38012Sejakowatz 49652a38012Sejakowatz status_t rv; 4978c6a6096Sbeveloper producer_format_proposal_request request1; 4988c6a6096Sbeveloper producer_format_proposal_reply reply1; 49952a38012Sejakowatz 50052a38012Sejakowatz // BBufferProducer::FormatProposal 5018c6a6096Sbeveloper request1.output = from; 5028c6a6096Sbeveloper request1.format = *io_format; 5038c6a6096Sbeveloper rv = QueryPort(from.port, PRODUCER_FORMAT_PROPOSAL, &request1, sizeof(request1), &reply1, sizeof(reply1)); 5048c6a6096Sbeveloper if (rv != B_OK) { 505353b9f6bSbeveloper FATAL("BMediaRoster::Connect: aborted after BBufferProducer::FormatProposal, status = %#lx\n",rv); 50652a38012Sejakowatz return rv; 50752a38012Sejakowatz } 5088c6a6096Sbeveloper // reply1.format now contains the format proposed by the producer 5098c6a6096Sbeveloper 5108c6a6096Sbeveloper consumer_accept_format_request request2; 5118c6a6096Sbeveloper consumer_accept_format_reply reply2; 5128c6a6096Sbeveloper 5138c6a6096Sbeveloper // BBufferConsumer::AcceptFormat 5148c6a6096Sbeveloper request2.dest = to; 5158c6a6096Sbeveloper request2.format = reply1.format; 5168c6a6096Sbeveloper rv = QueryPort(to.port, CONSUMER_ACCEPT_FORMAT, &request2, sizeof(request2), &reply2, sizeof(reply2)); 5178c6a6096Sbeveloper if (rv != B_OK) { 518353b9f6bSbeveloper FATAL("BMediaRoster::Connect: aborted after BBufferConsumer::AcceptFormat, status = %#lx\n",rv); 5198c6a6096Sbeveloper return rv; 5208c6a6096Sbeveloper } 5218c6a6096Sbeveloper // reply2.format now contains the format accepted by the consumer 5228c6a6096Sbeveloper 5238c6a6096Sbeveloper // BBufferProducer::PrepareToConnect 5248c6a6096Sbeveloper producer_prepare_to_connect_request request3; 5258c6a6096Sbeveloper producer_prepare_to_connect_reply reply3; 5268c6a6096Sbeveloper 5278c6a6096Sbeveloper request3.source = from; 5288c6a6096Sbeveloper request3.destination = to; 5298c6a6096Sbeveloper request3.format = reply2.format; 5308c6a6096Sbeveloper strcpy(request3.name, "XXX some default name"); // XXX fix this 5318c6a6096Sbeveloper rv = QueryPort(from.port, PRODUCER_PREPARE_TO_CONNECT, &request3, sizeof(request3), &reply3, sizeof(reply3)); 5328c6a6096Sbeveloper if (rv != B_OK) { 533353b9f6bSbeveloper FATAL("BMediaRoster::Connect: aborted after BBufferProducer::PrepareToConnect, status = %#lx\n",rv); 5348c6a6096Sbeveloper return rv; 5358c6a6096Sbeveloper } 5368c6a6096Sbeveloper // reply3.format is still our pretty media format 5378c6a6096Sbeveloper // reply3.out_source the real source to be used for the connection 5388c6a6096Sbeveloper // reply3.name the name BBufferConsumer::Connected will see in the outInput->name argument 5398c6a6096Sbeveloper 5408c6a6096Sbeveloper // BBufferConsumer::Connected 5418c6a6096Sbeveloper consumer_connected_request request4; 5428c6a6096Sbeveloper consumer_connected_reply reply4; 5438c6a6096Sbeveloper status_t con_status; 5448c6a6096Sbeveloper 5458c6a6096Sbeveloper request4.producer = reply3.out_source; 5468c6a6096Sbeveloper request4.where = to; 5478c6a6096Sbeveloper request4.with_format = reply3.format; 5488c6a6096Sbeveloper con_status = QueryPort(to.port, CONSUMER_CONNECTED, &request4, sizeof(request4), &reply4, sizeof(reply4)); 5498c6a6096Sbeveloper if (con_status != B_OK) { 550353b9f6bSbeveloper FATAL("BMediaRoster::Connect: aborting after BBufferConsumer::Connected, status = %#lx\n",con_status); 5518c6a6096Sbeveloper // we do NOT return here! 5528c6a6096Sbeveloper } 5538c6a6096Sbeveloper // con_status contains the status code to be supplied to BBufferProducer::Connect's status argument 5548c6a6096Sbeveloper // reply4.input contains the media_input that describes the connection from the consumer point of view 5558c6a6096Sbeveloper 5568c6a6096Sbeveloper // BBufferProducer::Connect 5578c6a6096Sbeveloper producer_connect_request request5; 5588c6a6096Sbeveloper producer_connect_reply reply5; 5598c6a6096Sbeveloper 5608c6a6096Sbeveloper request5.error = con_status; 5618c6a6096Sbeveloper request5.source = reply3.out_source; 5628c6a6096Sbeveloper request5.destination = reply4.input.destination; 5638c6a6096Sbeveloper request5.format = reply3.format; // XXX reply4.input.format ??? 5648c6a6096Sbeveloper strcpy(request5.name, reply4.input.name); 5650caff283Sbeveloper rv = QueryPort(reply4.input.source.port, PRODUCER_CONNECT, &request5, sizeof(request5), &reply5, sizeof(reply5)); 5668c6a6096Sbeveloper if (con_status != B_OK) { 567353b9f6bSbeveloper FATAL("BMediaRoster::Connect: aborted\n"); 5688c6a6096Sbeveloper return con_status; 5698c6a6096Sbeveloper } 5708c6a6096Sbeveloper if (rv != B_OK) { 571353b9f6bSbeveloper FATAL("BMediaRoster::Connect: aborted after BBufferProducer::Connect, status = %#lx\n",rv); 5728c6a6096Sbeveloper return rv; 5738c6a6096Sbeveloper } 5748c6a6096Sbeveloper // reply5.name contains the name assigned to the connection by the producer 5758c6a6096Sbeveloper 5768c6a6096Sbeveloper // find the output node 5778c6a6096Sbeveloper // XXX isn't there a easier way? 5788c6a6096Sbeveloper media_node sourcenode; 5798c6a6096Sbeveloper GetNodeFor(NodeIDFor(from.port), &sourcenode); 5808c6a6096Sbeveloper ReleaseNode(sourcenode); 5818c6a6096Sbeveloper 5828c6a6096Sbeveloper // initilize connection info 5838c6a6096Sbeveloper *io_format = reply3.format; 5848c6a6096Sbeveloper *out_input = reply4.input; 5858c6a6096Sbeveloper out_output->node = sourcenode; 5868c6a6096Sbeveloper out_output->source = reply4.input.source; 5878c6a6096Sbeveloper out_output->destination = reply4.input.destination; 5888c6a6096Sbeveloper out_output->format = reply4.input.format; 5898c6a6096Sbeveloper strcpy(out_output->name, reply5.name); 5908c6a6096Sbeveloper 5918c6a6096Sbeveloper // the connection is now made 5928c6a6096Sbeveloper 5938c6a6096Sbeveloper 5948c6a6096Sbeveloper // XXX register connection with server 5959e9417d2Sbeveloper // XXX we should just send a notification, instead of republishing all endpoints 59676669a29Sbeveloper List<media_output> outlist; 59776669a29Sbeveloper List<media_input> inlist; 59876669a29Sbeveloper if (B_OK == GetAllOutputs(out_output->node , &outlist)) 59976669a29Sbeveloper PublishOutputs(out_output->node , &outlist); 60076669a29Sbeveloper if (B_OK == GetAllInputs(out_input->node , &inlist)) 60176669a29Sbeveloper PublishInputs(out_input->node, &inlist); 6028c6a6096Sbeveloper 6038c6a6096Sbeveloper 6048c6a6096Sbeveloper // XXX if (mute) BBufferProducer::EnableOutput(false) 6059e9417d2Sbeveloper if (in_flags & B_CONNECT_MUTED) { 6069e9417d2Sbeveloper } 6078c6a6096Sbeveloper 6088c6a6096Sbeveloper 6099e9417d2Sbeveloper // send a notification 6109e9417d2Sbeveloper BPrivate::media::notifications::ConnectionMade(*out_input, *out_output, *io_format); 6119e9417d2Sbeveloper 6128c6a6096Sbeveloper return B_OK; 6138c6a6096Sbeveloper }; 61452a38012Sejakowatz 61552a38012Sejakowatz 61652a38012Sejakowatz status_t 6179e9417d2Sbeveloper BMediaRoster::Disconnect(media_node_id source_nodeid, 61852a38012Sejakowatz const media_source & source, 6199e9417d2Sbeveloper media_node_id destination_nodeid, 62052a38012Sejakowatz const media_destination & destination) 62152a38012Sejakowatz { 6229e9417d2Sbeveloper CALLED(); 6239e9417d2Sbeveloper if (source_nodeid <= 0) { 624353b9f6bSbeveloper FATAL("BMediaRoster::Disconnect: source media_node_id invalid\n"); 6259e9417d2Sbeveloper return B_MEDIA_BAD_SOURCE; 6269e9417d2Sbeveloper } 6279e9417d2Sbeveloper if (destination_nodeid <= 0) { 628353b9f6bSbeveloper FATAL("BMediaRoster::Disconnect: source media_node_id invalid\n"); 6299e9417d2Sbeveloper return B_MEDIA_BAD_DESTINATION; 6309e9417d2Sbeveloper } 6319e9417d2Sbeveloper if (source == media_source::null) { 632353b9f6bSbeveloper FATAL("BMediaRoster::Disconnect: media_source invalid\n"); 6339e9417d2Sbeveloper return B_MEDIA_BAD_SOURCE; 6349e9417d2Sbeveloper } 6359e9417d2Sbeveloper if (destination == media_destination::null) { 636353b9f6bSbeveloper FATAL("BMediaRoster::Disconnect: media_destination invalid\n"); 6379e9417d2Sbeveloper return B_MEDIA_BAD_DESTINATION; 6389e9417d2Sbeveloper } 6399e9417d2Sbeveloper 6409e9417d2Sbeveloper producer_disconnect_request request2; 6419e9417d2Sbeveloper producer_disconnect_reply reply2; 6429e9417d2Sbeveloper consumer_disconnected_request request1; 6439e9417d2Sbeveloper consumer_disconnected_reply reply1; 6449e9417d2Sbeveloper status_t rv1, rv2; 6459e9417d2Sbeveloper 6469e9417d2Sbeveloper // XXX we should ask the server if this connection really exists 6479e9417d2Sbeveloper 6489e9417d2Sbeveloper request1.source = source; 6499e9417d2Sbeveloper request1.destination = destination; 6509e9417d2Sbeveloper request2.source = source; 6519e9417d2Sbeveloper request2.destination = destination; 6529e9417d2Sbeveloper 6539e9417d2Sbeveloper rv1 = QueryPort(source.port, PRODUCER_DISCONNECT, &request1, sizeof(request1), &reply1, sizeof(reply1)); 6549e9417d2Sbeveloper rv2 = QueryPort(destination.port, CONSUMER_DISCONNECTED, &request2, sizeof(request2), &reply2, sizeof(reply2)); 6559e9417d2Sbeveloper 6569e9417d2Sbeveloper // XXX unregister connection with server 6579e9417d2Sbeveloper // XXX we should just send a notification, instead of republishing all endpoints 65876669a29Sbeveloper List<media_output> outlist; 65976669a29Sbeveloper List<media_input> inlist; 6609e9417d2Sbeveloper media_node sourcenode; 6619e9417d2Sbeveloper media_node destnode; 6629e9417d2Sbeveloper if (B_OK == GetNodeFor(source_nodeid, &sourcenode)) { 66376669a29Sbeveloper if (B_OK == GetAllOutputs(sourcenode , &outlist)) 66476669a29Sbeveloper PublishOutputs(sourcenode , &outlist); 6659e9417d2Sbeveloper ReleaseNode(sourcenode); 666353b9f6bSbeveloper } else FATAL("BMediaRoster::Disconnect: source GetNodeFor failed\n"); 6679e9417d2Sbeveloper if (B_OK == GetNodeFor(destination_nodeid, &destnode)) { 66876669a29Sbeveloper if (B_OK == GetAllInputs(destnode , &inlist)) 66976669a29Sbeveloper PublishInputs(destnode, &inlist); 6709e9417d2Sbeveloper ReleaseNode(destnode); 671353b9f6bSbeveloper } else FATAL("BMediaRoster::Disconnect: dest GetNodeFor failed\n"); 6729e9417d2Sbeveloper 6739e9417d2Sbeveloper 6749e9417d2Sbeveloper // send a notification 6759e9417d2Sbeveloper BPrivate::media::notifications::ConnectionBroken(source, destination); 6769e9417d2Sbeveloper 6779e9417d2Sbeveloper return (rv1 != B_OK || rv2 != B_OK) ? B_ERROR : B_OK; 67852a38012Sejakowatz } 67952a38012Sejakowatz 68052a38012Sejakowatz 68152a38012Sejakowatz status_t 68252a38012Sejakowatz BMediaRoster::StartNode(const media_node & node, 68352a38012Sejakowatz bigtime_t at_performance_time) 68452a38012Sejakowatz { 68552a38012Sejakowatz CALLED(); 6869e9417d2Sbeveloper if (node.node <= 0) 68752a38012Sejakowatz return B_MEDIA_BAD_NODE; 68852a38012Sejakowatz 689*0e21b167Sbeveloper printf("BMediaRoster::StartNode, node %ld, at perf %Ld\n", node.node, at_performance_time); 690*0e21b167Sbeveloper 6916396865dSbeveloper node_start_command command; 6926396865dSbeveloper command.performance_time = at_performance_time; 69352a38012Sejakowatz 6946396865dSbeveloper return SendToPort(node.port, NODE_START, &command, sizeof(command)); 69552a38012Sejakowatz } 69652a38012Sejakowatz 69752a38012Sejakowatz 69852a38012Sejakowatz status_t 69952a38012Sejakowatz BMediaRoster::StopNode(const media_node & node, 70052a38012Sejakowatz bigtime_t at_performance_time, 70152a38012Sejakowatz bool immediate) 70252a38012Sejakowatz { 70352a38012Sejakowatz CALLED(); 7049e9417d2Sbeveloper if (node.node <= 0) 70552a38012Sejakowatz return B_MEDIA_BAD_NODE; 70652a38012Sejakowatz 707*0e21b167Sbeveloper printf("BMediaRoster::StopNode, node %ld, at perf %Ld %s\n", node.node, at_performance_time, immediate ? "NOW" : ""); 708*0e21b167Sbeveloper 7096396865dSbeveloper node_stop_command command; 7106396865dSbeveloper command.performance_time = at_performance_time; 7116396865dSbeveloper command.immediate = immediate; 71252a38012Sejakowatz 7136396865dSbeveloper return SendToPort(node.port, NODE_STOP, &command, sizeof(command)); 71452a38012Sejakowatz } 71552a38012Sejakowatz 71652a38012Sejakowatz 71752a38012Sejakowatz status_t 71852a38012Sejakowatz BMediaRoster::SeekNode(const media_node & node, 71952a38012Sejakowatz bigtime_t to_media_time, 72052a38012Sejakowatz bigtime_t at_performance_time) 72152a38012Sejakowatz { 72252a38012Sejakowatz CALLED(); 7239e9417d2Sbeveloper if (node.node <= 0) 72452a38012Sejakowatz return B_MEDIA_BAD_NODE; 72552a38012Sejakowatz 726*0e21b167Sbeveloper printf("BMediaRoster::SeekNode, node %ld, at perf %Ld, to perf %Ld\n", node.node, at_performance_time, to_media_time); 727*0e21b167Sbeveloper 7286396865dSbeveloper node_seek_command command; 7296396865dSbeveloper command.media_time = to_media_time; 7306396865dSbeveloper command.performance_time = at_performance_time; 73152a38012Sejakowatz 7326396865dSbeveloper return SendToPort(node.port, NODE_SEEK, &command, sizeof(command)); 73352a38012Sejakowatz } 73452a38012Sejakowatz 73552a38012Sejakowatz 73652a38012Sejakowatz status_t 73752a38012Sejakowatz BMediaRoster::StartTimeSource(const media_node & node, 73852a38012Sejakowatz bigtime_t at_real_time) 73952a38012Sejakowatz { 74052a38012Sejakowatz CALLED(); 741*0e21b167Sbeveloper if (node.node <= 0) { 742*0e21b167Sbeveloper FATAL("BMediaRoster::StartTimeSource node invalid\n"); 74352a38012Sejakowatz return B_MEDIA_BAD_NODE; 744*0e21b167Sbeveloper } 745*0e21b167Sbeveloper if ((node.kind & B_TIME_SOURCE) == 0) { 746*0e21b167Sbeveloper FATAL("BMediaRoster::StartTimeSource node is no timesource invalid\n"); 74752a38012Sejakowatz return B_MEDIA_BAD_NODE; 748*0e21b167Sbeveloper } 749*0e21b167Sbeveloper 750*0e21b167Sbeveloper printf("BMediaRoster::StartTimeSource, node %ld, at real %Ld\n", node.node, at_real_time); 75152a38012Sejakowatz 75252a38012Sejakowatz BTimeSource::time_source_op_info msg; 75352a38012Sejakowatz msg.op = BTimeSource::B_TIMESOURCE_START; 75452a38012Sejakowatz msg.real_time = at_real_time; 75552a38012Sejakowatz 75652a38012Sejakowatz return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg)); 75752a38012Sejakowatz } 75852a38012Sejakowatz 75952a38012Sejakowatz 76052a38012Sejakowatz status_t 76152a38012Sejakowatz BMediaRoster::StopTimeSource(const media_node & node, 76252a38012Sejakowatz bigtime_t at_real_time, 76352a38012Sejakowatz bool immediate) 76452a38012Sejakowatz { 76552a38012Sejakowatz CALLED(); 766*0e21b167Sbeveloper if (node.node <= 0) { 767*0e21b167Sbeveloper FATAL("BMediaRoster::StartTimeSource node invalid\n"); 76852a38012Sejakowatz return B_MEDIA_BAD_NODE; 769*0e21b167Sbeveloper } 770*0e21b167Sbeveloper if ((node.kind & B_TIME_SOURCE) == 0) { 771*0e21b167Sbeveloper FATAL("BMediaRoster::StartTimeSource node is no timesource invalid\n"); 77252a38012Sejakowatz return B_MEDIA_BAD_NODE; 773*0e21b167Sbeveloper } 774*0e21b167Sbeveloper 775*0e21b167Sbeveloper printf("BMediaRoster::StopTimeSource, node %ld, at real %Ld %s\n", node.node, at_real_time, immediate ? "NOW" : ""); 77652a38012Sejakowatz 77752a38012Sejakowatz BTimeSource::time_source_op_info msg; 77852a38012Sejakowatz msg.op = immediate ? BTimeSource::B_TIMESOURCE_STOP_IMMEDIATELY : BTimeSource::B_TIMESOURCE_STOP; 77952a38012Sejakowatz msg.real_time = at_real_time; 78052a38012Sejakowatz 78152a38012Sejakowatz return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg)); 78252a38012Sejakowatz } 78352a38012Sejakowatz 78452a38012Sejakowatz 78552a38012Sejakowatz status_t 78652a38012Sejakowatz BMediaRoster::SeekTimeSource(const media_node & node, 78752a38012Sejakowatz bigtime_t to_performance_time, 78852a38012Sejakowatz bigtime_t at_real_time) 78952a38012Sejakowatz { 79052a38012Sejakowatz CALLED(); 791*0e21b167Sbeveloper if (node.node <= 0) { 792*0e21b167Sbeveloper FATAL("BMediaRoster::StartTimeSource node invalid\n"); 79352a38012Sejakowatz return B_MEDIA_BAD_NODE; 794*0e21b167Sbeveloper } 795*0e21b167Sbeveloper if ((node.kind & B_TIME_SOURCE) == 0) { 796*0e21b167Sbeveloper FATAL("BMediaRoster::StartTimeSource node is no timesource invalid\n"); 79752a38012Sejakowatz return B_MEDIA_BAD_NODE; 798*0e21b167Sbeveloper } 799*0e21b167Sbeveloper 800*0e21b167Sbeveloper printf("BMediaRoster::SeekTimeSource, node %ld, at real %Ld, to perf %Ld\n", node.node, at_real_time, to_performance_time); 80152a38012Sejakowatz 80252a38012Sejakowatz BTimeSource::time_source_op_info msg; 80352a38012Sejakowatz msg.op = BTimeSource::B_TIMESOURCE_SEEK; 80452a38012Sejakowatz msg.real_time = at_real_time; 80552a38012Sejakowatz msg.performance_time = to_performance_time; 80652a38012Sejakowatz 80752a38012Sejakowatz return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg)); 80852a38012Sejakowatz } 80952a38012Sejakowatz 81052a38012Sejakowatz 81152a38012Sejakowatz status_t 81252a38012Sejakowatz BMediaRoster::SyncToNode(const media_node & node, 81352a38012Sejakowatz bigtime_t at_time, 81452a38012Sejakowatz bigtime_t timeout) 81552a38012Sejakowatz { 81652a38012Sejakowatz UNIMPLEMENTED(); 81752a38012Sejakowatz return B_ERROR; 81852a38012Sejakowatz } 81952a38012Sejakowatz 82052a38012Sejakowatz 82152a38012Sejakowatz status_t 82252a38012Sejakowatz BMediaRoster::SetRunModeNode(const media_node & node, 82352a38012Sejakowatz BMediaNode::run_mode mode) 82452a38012Sejakowatz { 82552a38012Sejakowatz CALLED(); 8269e9417d2Sbeveloper if (node.node <= 0) 82752a38012Sejakowatz return B_MEDIA_BAD_NODE; 82852a38012Sejakowatz 829dfb2ad61Sbeveloper node_set_run_mode_command msg; 83052a38012Sejakowatz msg.mode = mode; 83152a38012Sejakowatz 83252a38012Sejakowatz return write_port(node.port, NODE_SET_RUN_MODE, &msg, sizeof(msg)); 83352a38012Sejakowatz } 83452a38012Sejakowatz 83552a38012Sejakowatz 83652a38012Sejakowatz status_t 83752a38012Sejakowatz BMediaRoster::PrerollNode(const media_node & node) 83852a38012Sejakowatz { 83952a38012Sejakowatz CALLED(); 8409e9417d2Sbeveloper if (node.node <= 0) 84152a38012Sejakowatz return B_MEDIA_BAD_NODE; 84252a38012Sejakowatz 84352a38012Sejakowatz char dummy; 84452a38012Sejakowatz return write_port(node.port, NODE_PREROLL, &dummy, sizeof(dummy)); 84552a38012Sejakowatz } 84652a38012Sejakowatz 84752a38012Sejakowatz 84852a38012Sejakowatz status_t 84952a38012Sejakowatz BMediaRoster::RollNode(const media_node & node, 85052a38012Sejakowatz bigtime_t startPerformance, 85152a38012Sejakowatz bigtime_t stopPerformance, 85252a38012Sejakowatz bigtime_t atMediaTime) 85352a38012Sejakowatz { 85452a38012Sejakowatz UNIMPLEMENTED(); 85552a38012Sejakowatz return B_ERROR; 85652a38012Sejakowatz } 85752a38012Sejakowatz 85852a38012Sejakowatz 85952a38012Sejakowatz status_t 86052a38012Sejakowatz BMediaRoster::SetProducerRunModeDelay(const media_node & node, 86152a38012Sejakowatz bigtime_t delay, 86252a38012Sejakowatz BMediaNode::run_mode mode) 86352a38012Sejakowatz { 86452a38012Sejakowatz UNIMPLEMENTED(); 86552a38012Sejakowatz return B_ERROR; 86652a38012Sejakowatz } 86752a38012Sejakowatz 86852a38012Sejakowatz 86952a38012Sejakowatz status_t 87052a38012Sejakowatz BMediaRoster::SetProducerRate(const media_node & producer, 87152a38012Sejakowatz int32 numer, 87252a38012Sejakowatz int32 denom) 87352a38012Sejakowatz { 87452a38012Sejakowatz CALLED(); 87552a38012Sejakowatz if (producer.node == 0) 87652a38012Sejakowatz return B_MEDIA_BAD_NODE; 87752a38012Sejakowatz if ((producer.kind & B_BUFFER_PRODUCER) == 0) 87852a38012Sejakowatz return B_MEDIA_BAD_NODE; 87952a38012Sejakowatz 880dfb2ad61Sbeveloper producer_set_play_rate_request msg; 881dfb2ad61Sbeveloper producer_set_play_rate_reply reply; 88252a38012Sejakowatz status_t rv; 88352a38012Sejakowatz int32 code; 88452a38012Sejakowatz 88552a38012Sejakowatz msg.numer = numer; 88652a38012Sejakowatz msg.denom = denom; 88752a38012Sejakowatz msg.reply_port = _PortPool->GetPort(); 88852a38012Sejakowatz rv = write_port(producer.node, PRODUCER_SET_PLAY_RATE, &msg, sizeof(msg)); 88952a38012Sejakowatz if (rv != B_OK) { 89052a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 89152a38012Sejakowatz return rv; 89252a38012Sejakowatz } 89352a38012Sejakowatz rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); 89452a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 89552a38012Sejakowatz return (rv < B_OK) ? rv : reply.result; 89652a38012Sejakowatz } 89752a38012Sejakowatz 89852a38012Sejakowatz 89952a38012Sejakowatz /* Nodes will have available inputs/outputs as long as they are capable */ 90052a38012Sejakowatz /* of accepting more connections. The node may create an additional */ 90152a38012Sejakowatz /* output or input as the currently available is taken into usage. */ 90252a38012Sejakowatz status_t 90352a38012Sejakowatz BMediaRoster::GetLiveNodeInfo(const media_node & node, 90452a38012Sejakowatz live_node_info * out_live_info) 90552a38012Sejakowatz { 9069e9417d2Sbeveloper CALLED(); 9079e9417d2Sbeveloper if (out_live_info == NULL) 9089e9417d2Sbeveloper return B_BAD_VALUE; 9099e9417d2Sbeveloper if (node.node <= 0) 9109e9417d2Sbeveloper return B_MEDIA_BAD_NODE; 9119e9417d2Sbeveloper 9129e9417d2Sbeveloper server_get_live_node_info_request request; 9139e9417d2Sbeveloper server_get_live_node_info_reply reply; 9149e9417d2Sbeveloper status_t rv; 9159e9417d2Sbeveloper 9169e9417d2Sbeveloper request.node = node; 9179e9417d2Sbeveloper 9181299bfb2Sbeveloper rv = QueryServer(SERVER_GET_LIVE_NODE_INFO, &request, sizeof(request), &reply, sizeof(reply)); 9199e9417d2Sbeveloper if (rv != B_OK) 9209e9417d2Sbeveloper return rv; 9219e9417d2Sbeveloper 9229e9417d2Sbeveloper *out_live_info = reply.live_info; 9239e9417d2Sbeveloper return B_OK; 92452a38012Sejakowatz } 92552a38012Sejakowatz 92652a38012Sejakowatz 92752a38012Sejakowatz status_t 92852a38012Sejakowatz BMediaRoster::GetLiveNodes(live_node_info * out_live_nodes, 92952a38012Sejakowatz int32 * io_total_count, 93052a38012Sejakowatz const media_format * has_input, 93152a38012Sejakowatz const media_format * has_output, 93252a38012Sejakowatz const char * name, 93352a38012Sejakowatz uint64 node_kinds) 93452a38012Sejakowatz { 9359e9417d2Sbeveloper CALLED(); 9369e9417d2Sbeveloper if (out_live_nodes == NULL || io_total_count == NULL) 9379e9417d2Sbeveloper return B_BAD_VALUE; 9389e9417d2Sbeveloper if (*io_total_count <= 0) 9399e9417d2Sbeveloper return B_BAD_VALUE; 9409e9417d2Sbeveloper 9419e9417d2Sbeveloper // XXX we also support the wildcard search as GetDormantNodes does. This needs to be documented 9429e9417d2Sbeveloper 9439e9417d2Sbeveloper server_get_live_nodes_request request; 9449e9417d2Sbeveloper server_get_live_nodes_reply reply; 9459e9417d2Sbeveloper status_t rv; 9469e9417d2Sbeveloper 9479e9417d2Sbeveloper request.maxcount = *io_total_count; 9489e9417d2Sbeveloper request.has_input = (bool) has_input; 9499e9417d2Sbeveloper if (has_input) 9509e9417d2Sbeveloper request.inputformat = *has_input; // XXX we should not make a flat copy of media_format 9519e9417d2Sbeveloper request.has_output = (bool) has_output; 9529e9417d2Sbeveloper if (has_output) 9539e9417d2Sbeveloper request.outputformat = *has_output; // XXX we should not make a flat copy of media_format 9549e9417d2Sbeveloper request.has_name = (bool) name; 9559e9417d2Sbeveloper if (name) { 9569e9417d2Sbeveloper int len = strlen(name); 9579e9417d2Sbeveloper len = min_c(len, (int)sizeof(request.name) - 1); 9589e9417d2Sbeveloper memcpy(request.name, name, len); 9599e9417d2Sbeveloper request.name[len] = 0; 9609e9417d2Sbeveloper } 9619e9417d2Sbeveloper request.require_kinds = node_kinds; 9629e9417d2Sbeveloper 9639e9417d2Sbeveloper rv = QueryServer(SERVER_GET_LIVE_NODES, &request, sizeof(request), &reply, sizeof(reply)); 9649e9417d2Sbeveloper if (rv != B_OK) { 965353b9f6bSbeveloper FATAL("BMediaRoster::GetLiveNodes failed\n"); 9661299bfb2Sbeveloper *io_total_count = 0; 9679e9417d2Sbeveloper return rv; 9689e9417d2Sbeveloper } 9699e9417d2Sbeveloper 9709e9417d2Sbeveloper if (reply.count > MAX_LIVE_INFO) { 9719e9417d2Sbeveloper live_node_info *live_info; 9729e9417d2Sbeveloper area_id clone; 9739e9417d2Sbeveloper 9749e9417d2Sbeveloper clone = clone_area("live_node_info clone", reinterpret_cast<void **>(&live_info), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, reply.area); 9759e9417d2Sbeveloper if (clone < B_OK) { 976353b9f6bSbeveloper FATAL("BMediaRoster::GetLiveNodes failed to clone area, %#lx\n", clone); 9779e9417d2Sbeveloper delete_area(reply.area); 9781299bfb2Sbeveloper *io_total_count = 0; 97952a38012Sejakowatz return B_ERROR; 98052a38012Sejakowatz } 98152a38012Sejakowatz 9829e9417d2Sbeveloper for (int32 i = 0; i < reply.count; i++) { 9839e9417d2Sbeveloper out_live_nodes[i] = live_info[i]; 9849e9417d2Sbeveloper } 9859e9417d2Sbeveloper 9869e9417d2Sbeveloper delete_area(clone); 9879e9417d2Sbeveloper delete_area(reply.area); 9889e9417d2Sbeveloper } else { 9899e9417d2Sbeveloper for (int32 i = 0; i < reply.count; i++) { 9909e9417d2Sbeveloper out_live_nodes[i] = reply.live_info[i]; 9919e9417d2Sbeveloper } 9929e9417d2Sbeveloper } 9939e9417d2Sbeveloper *io_total_count = reply.count; 9949e9417d2Sbeveloper 9959e9417d2Sbeveloper return B_OK; 9969e9417d2Sbeveloper } 9979e9417d2Sbeveloper 99852a38012Sejakowatz 99952a38012Sejakowatz status_t 100052a38012Sejakowatz BMediaRoster::GetFreeInputsFor(const media_node & node, 100152a38012Sejakowatz media_input * out_free_inputs, 100252a38012Sejakowatz int32 buf_num_inputs, 100352a38012Sejakowatz int32 * out_total_count, 100452a38012Sejakowatz media_type filter_type) 100552a38012Sejakowatz { 10063620737cSbeveloper CALLED(); 10079e9417d2Sbeveloper if (node.node <= 0 || (node.kind & B_BUFFER_CONSUMER) == 0) 10083620737cSbeveloper return B_MEDIA_BAD_NODE; 10093620737cSbeveloper if (out_free_inputs == NULL || out_total_count == NULL) 10103620737cSbeveloper return B_BAD_VALUE; 10113620737cSbeveloper 101276669a29Sbeveloper List<media_input> list; 10133620737cSbeveloper media_input *input; 10143620737cSbeveloper status_t rv; 10153620737cSbeveloper 10161299bfb2Sbeveloper *out_total_count = 0; 10171299bfb2Sbeveloper 101876669a29Sbeveloper rv = GetAllInputs(node, &list); 10193620737cSbeveloper if (B_OK != rv) 10203620737cSbeveloper return rv; 10213620737cSbeveloper 102276669a29Sbeveloper int32 i; 102376669a29Sbeveloper for (i = 0, list.Rewind(); list.GetNext(&input); i++) { 10243620737cSbeveloper if (filter_type != B_MEDIA_UNKNOWN_TYPE && filter_type != input->format.type) 10253620737cSbeveloper continue; // media_type used, but doesn't match 10263620737cSbeveloper if (input->source != media_source::null) 10273620737cSbeveloper continue; // consumer source already connected 10283620737cSbeveloper out_free_inputs[i] = *input; 10293620737cSbeveloper *out_total_count += 1; 10303620737cSbeveloper buf_num_inputs -= 1; 10313620737cSbeveloper if (buf_num_inputs == 0) 10323620737cSbeveloper break; 10333620737cSbeveloper } 10343620737cSbeveloper 103576669a29Sbeveloper PublishInputs(node, &list); 10363620737cSbeveloper return B_OK; 103752a38012Sejakowatz } 103852a38012Sejakowatz 103952a38012Sejakowatz 104052a38012Sejakowatz status_t 104152a38012Sejakowatz BMediaRoster::GetConnectedInputsFor(const media_node & node, 104252a38012Sejakowatz media_input * out_active_inputs, 104352a38012Sejakowatz int32 buf_num_inputs, 104452a38012Sejakowatz int32 * out_total_count) 104552a38012Sejakowatz { 10463620737cSbeveloper CALLED(); 10479e9417d2Sbeveloper if (node.node <= 0 || (node.kind & B_BUFFER_CONSUMER) == 0) 10483620737cSbeveloper return B_MEDIA_BAD_NODE; 10493620737cSbeveloper if (out_active_inputs == NULL || out_total_count == NULL) 10503620737cSbeveloper return B_BAD_VALUE; 10513620737cSbeveloper 105276669a29Sbeveloper List<media_input> list; 10533620737cSbeveloper media_input *input; 10543620737cSbeveloper status_t rv; 10553620737cSbeveloper 10561299bfb2Sbeveloper *out_total_count = 0; 10571299bfb2Sbeveloper 105876669a29Sbeveloper rv = GetAllInputs(node, &list); 10593620737cSbeveloper if (B_OK != rv) 10603620737cSbeveloper return rv; 10613620737cSbeveloper 106276669a29Sbeveloper int32 i; 106376669a29Sbeveloper for (i = 0, list.Rewind(); list.GetNext(&input); i++) { 10643620737cSbeveloper if (input->source == media_source::null) 10653620737cSbeveloper continue; // consumer source not connected 10663620737cSbeveloper out_active_inputs[i] = *input; 10673620737cSbeveloper *out_total_count += 1; 10683620737cSbeveloper buf_num_inputs -= 1; 10693620737cSbeveloper if (buf_num_inputs == 0) 10703620737cSbeveloper break; 10713620737cSbeveloper } 10723620737cSbeveloper 107376669a29Sbeveloper PublishInputs(node, &list); 10743620737cSbeveloper return B_OK; 107552a38012Sejakowatz } 107652a38012Sejakowatz 107752a38012Sejakowatz 107852a38012Sejakowatz status_t 107952a38012Sejakowatz BMediaRoster::GetAllInputsFor(const media_node & node, 108052a38012Sejakowatz media_input * out_inputs, 108152a38012Sejakowatz int32 buf_num_inputs, 108252a38012Sejakowatz int32 * out_total_count) 108352a38012Sejakowatz { 108452a38012Sejakowatz CALLED(); 10859e9417d2Sbeveloper if (node.node <= 0 || (node.kind & B_BUFFER_CONSUMER) == 0) 108652a38012Sejakowatz return B_MEDIA_BAD_NODE; 108752a38012Sejakowatz if (out_inputs == NULL || out_total_count == NULL) 108852a38012Sejakowatz return B_BAD_VALUE; 108952a38012Sejakowatz 109076669a29Sbeveloper List<media_input> list; 10913620737cSbeveloper media_input *input; 109252a38012Sejakowatz status_t rv; 109352a38012Sejakowatz 10941299bfb2Sbeveloper *out_total_count = 0; 10951299bfb2Sbeveloper 109676669a29Sbeveloper rv = GetAllInputs(node, &list); 10973620737cSbeveloper if (B_OK != rv) 10983620737cSbeveloper return rv; 10993620737cSbeveloper 110076669a29Sbeveloper int32 i; 110176669a29Sbeveloper for (i = 0, list.Rewind(); list.GetNext(&input); i++) { 11023620737cSbeveloper out_inputs[i] = *input; 110352a38012Sejakowatz *out_total_count += 1; 11043620737cSbeveloper buf_num_inputs -= 1; 11053620737cSbeveloper if (buf_num_inputs == 0) 11063620737cSbeveloper break; 110752a38012Sejakowatz } 110852a38012Sejakowatz 110976669a29Sbeveloper PublishInputs(node, &list); 11103620737cSbeveloper return B_OK; 111152a38012Sejakowatz } 111252a38012Sejakowatz 111352a38012Sejakowatz 111452a38012Sejakowatz status_t 111552a38012Sejakowatz BMediaRoster::GetFreeOutputsFor(const media_node & node, 111652a38012Sejakowatz media_output * out_free_outputs, 111752a38012Sejakowatz int32 buf_num_outputs, 111852a38012Sejakowatz int32 * out_total_count, 111952a38012Sejakowatz media_type filter_type) 112052a38012Sejakowatz { 11213620737cSbeveloper CALLED(); 11229e9417d2Sbeveloper if (node.node <= 0 || (node.kind & B_BUFFER_PRODUCER) == 0) 11233620737cSbeveloper return B_MEDIA_BAD_NODE; 11243620737cSbeveloper if (out_free_outputs == NULL || out_total_count == NULL) 11253620737cSbeveloper return B_BAD_VALUE; 11263620737cSbeveloper 112776669a29Sbeveloper List<media_output> list; 11283620737cSbeveloper media_output *output; 11293620737cSbeveloper status_t rv; 11303620737cSbeveloper 11311299bfb2Sbeveloper *out_total_count = 0; 11321299bfb2Sbeveloper 113376669a29Sbeveloper rv = GetAllOutputs(node, &list); 11343620737cSbeveloper if (B_OK != rv) 11353620737cSbeveloper return rv; 11363620737cSbeveloper 113776669a29Sbeveloper int32 i; 113876669a29Sbeveloper for (i = 0, list.Rewind(); list.GetNext(&output); i++) { 11393620737cSbeveloper if (filter_type != B_MEDIA_UNKNOWN_TYPE && filter_type != output->format.type) 11403620737cSbeveloper continue; // media_type used, but doesn't match 11413620737cSbeveloper if (output->destination != media_destination::null) 11423620737cSbeveloper continue; // producer destination already connected 11433620737cSbeveloper out_free_outputs[i] = *output; 11443620737cSbeveloper *out_total_count += 1; 11453620737cSbeveloper buf_num_outputs -= 1; 11463620737cSbeveloper if (buf_num_outputs == 0) 11473620737cSbeveloper break; 11483620737cSbeveloper } 11493620737cSbeveloper 115076669a29Sbeveloper PublishOutputs(node, &list); 11513620737cSbeveloper return B_OK; 115252a38012Sejakowatz } 115352a38012Sejakowatz 115452a38012Sejakowatz 115552a38012Sejakowatz status_t 115652a38012Sejakowatz BMediaRoster::GetConnectedOutputsFor(const media_node & node, 115752a38012Sejakowatz media_output * out_active_outputs, 115852a38012Sejakowatz int32 buf_num_outputs, 115952a38012Sejakowatz int32 * out_total_count) 116052a38012Sejakowatz { 11613620737cSbeveloper CALLED(); 11629e9417d2Sbeveloper if (node.node <= 0 || (node.kind & B_BUFFER_PRODUCER) == 0) 11633620737cSbeveloper return B_MEDIA_BAD_NODE; 11643620737cSbeveloper if (out_active_outputs == NULL || out_total_count == NULL) 11653620737cSbeveloper return B_BAD_VALUE; 11663620737cSbeveloper 116776669a29Sbeveloper List<media_output> list; 11683620737cSbeveloper media_output *output; 11693620737cSbeveloper status_t rv; 11703620737cSbeveloper 11711299bfb2Sbeveloper *out_total_count = 0; 11721299bfb2Sbeveloper 117376669a29Sbeveloper rv = GetAllOutputs(node, &list); 11743620737cSbeveloper if (B_OK != rv) 11753620737cSbeveloper return rv; 11763620737cSbeveloper 117776669a29Sbeveloper int32 i; 117876669a29Sbeveloper for (i = 0, list.Rewind(); list.GetNext(&output); i++) { 11793620737cSbeveloper if (output->destination == media_destination::null) 11803620737cSbeveloper continue; // producer destination not connected 11813620737cSbeveloper out_active_outputs[i] = *output; 11823620737cSbeveloper *out_total_count += 1; 11833620737cSbeveloper buf_num_outputs -= 1; 11843620737cSbeveloper if (buf_num_outputs == 0) 11853620737cSbeveloper break; 11863620737cSbeveloper } 11873620737cSbeveloper 118876669a29Sbeveloper PublishOutputs(node, &list); 11893620737cSbeveloper return B_OK; 119052a38012Sejakowatz } 119152a38012Sejakowatz 119252a38012Sejakowatz 119352a38012Sejakowatz status_t 119452a38012Sejakowatz BMediaRoster::GetAllOutputsFor(const media_node & node, 119552a38012Sejakowatz media_output * out_outputs, 119652a38012Sejakowatz int32 buf_num_outputs, 119752a38012Sejakowatz int32 * out_total_count) 119852a38012Sejakowatz { 119952a38012Sejakowatz CALLED(); 12009e9417d2Sbeveloper if (node.node <= 0 || (node.kind & B_BUFFER_PRODUCER) == 0) 120152a38012Sejakowatz return B_MEDIA_BAD_NODE; 120252a38012Sejakowatz if (out_outputs == NULL || out_total_count == NULL) 120352a38012Sejakowatz return B_BAD_VALUE; 120452a38012Sejakowatz 120576669a29Sbeveloper List<media_output> list; 12063620737cSbeveloper media_output *output; 120752a38012Sejakowatz status_t rv; 120852a38012Sejakowatz 12091299bfb2Sbeveloper *out_total_count = 0; 12101299bfb2Sbeveloper 121176669a29Sbeveloper rv = GetAllOutputs(node, &list); 12123620737cSbeveloper if (B_OK != rv) 12133620737cSbeveloper return rv; 12143620737cSbeveloper 121576669a29Sbeveloper int32 i; 121676669a29Sbeveloper for (i = 0, list.Rewind(); list.GetNext(&output); i++) { 12173620737cSbeveloper out_outputs[i] = *output; 121852a38012Sejakowatz *out_total_count += 1; 12193620737cSbeveloper buf_num_outputs -= 1; 12203620737cSbeveloper if (buf_num_outputs == 0) 12213620737cSbeveloper break; 122252a38012Sejakowatz } 122352a38012Sejakowatz 122476669a29Sbeveloper PublishOutputs(node, &list); 12253620737cSbeveloper return B_OK; 122652a38012Sejakowatz } 122752a38012Sejakowatz 122852a38012Sejakowatz 122952a38012Sejakowatz status_t 123052a38012Sejakowatz BMediaRoster::StartWatching(const BMessenger & where) 123152a38012Sejakowatz { 1232eae26d3dSbeveloper CALLED(); 1233eae26d3dSbeveloper if (!where.IsValid()) { 1234353b9f6bSbeveloper FATAL("BMediaRoster::StartWatching: messenger invalid!\n"); 1235eae26d3dSbeveloper return B_BAD_VALUE; 1236eae26d3dSbeveloper } 1237f4925104Sbeveloper return BPrivate::media::notifications::Register(where, media_node::null, B_MEDIA_WILDCARD); 123852a38012Sejakowatz } 123952a38012Sejakowatz 124052a38012Sejakowatz 124152a38012Sejakowatz status_t 124252a38012Sejakowatz BMediaRoster::StartWatching(const BMessenger & where, 124352a38012Sejakowatz int32 notificationType) 124452a38012Sejakowatz { 1245eae26d3dSbeveloper CALLED(); 1246eae26d3dSbeveloper if (!where.IsValid()) { 1247353b9f6bSbeveloper FATAL("BMediaRoster::StartWatching: messenger invalid!\n"); 1248eae26d3dSbeveloper return B_BAD_VALUE; 1249eae26d3dSbeveloper } 1250f4925104Sbeveloper if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) { 1251353b9f6bSbeveloper FATAL("BMediaRoster::StartWatching: notificationType invalid!\n"); 1252eae26d3dSbeveloper return B_BAD_VALUE; 1253eae26d3dSbeveloper } 1254f4925104Sbeveloper return BPrivate::media::notifications::Register(where, media_node::null, notificationType); 125552a38012Sejakowatz } 125652a38012Sejakowatz 125752a38012Sejakowatz 125852a38012Sejakowatz status_t 125952a38012Sejakowatz BMediaRoster::StartWatching(const BMessenger & where, 126052a38012Sejakowatz const media_node & node, 126152a38012Sejakowatz int32 notificationType) 126252a38012Sejakowatz { 1263eae26d3dSbeveloper CALLED(); 1264eae26d3dSbeveloper if (!where.IsValid()) { 1265353b9f6bSbeveloper FATAL("BMediaRoster::StartWatching: messenger invalid!\n"); 1266eae26d3dSbeveloper return B_BAD_VALUE; 1267eae26d3dSbeveloper } 12689e9417d2Sbeveloper if (node.node <= 0) { 1269353b9f6bSbeveloper FATAL("BMediaRoster::StartWatching: node invalid!\n"); 1270eae26d3dSbeveloper return B_MEDIA_BAD_NODE; 1271eae26d3dSbeveloper } 1272f4925104Sbeveloper if (false == BPrivate::media::notifications::IsValidNotificationRequest(true, notificationType)) { 1273353b9f6bSbeveloper FATAL("BMediaRoster::StartWatching: notificationType invalid!\n"); 1274eae26d3dSbeveloper return B_BAD_VALUE; 1275eae26d3dSbeveloper } 1276f4925104Sbeveloper return BPrivate::media::notifications::Register(where, node, notificationType); 127752a38012Sejakowatz } 127852a38012Sejakowatz 127952a38012Sejakowatz 128052a38012Sejakowatz status_t 128152a38012Sejakowatz BMediaRoster::StopWatching(const BMessenger & where) 128252a38012Sejakowatz { 1283eae26d3dSbeveloper CALLED(); 1284eae26d3dSbeveloper // messenger may already be invalid, so we don't check this 1285f4925104Sbeveloper return BPrivate::media::notifications::Unregister(where, media_node::null, B_MEDIA_WILDCARD); 128652a38012Sejakowatz } 128752a38012Sejakowatz 128852a38012Sejakowatz 128952a38012Sejakowatz status_t 129052a38012Sejakowatz BMediaRoster::StopWatching(const BMessenger & where, 129152a38012Sejakowatz int32 notificationType) 129252a38012Sejakowatz { 1293eae26d3dSbeveloper CALLED(); 1294eae26d3dSbeveloper // messenger may already be invalid, so we don't check this 1295f4925104Sbeveloper if (false == BPrivate::media::notifications::IsValidNotificationRequest(false, notificationType)) { 1296353b9f6bSbeveloper FATAL("BMediaRoster::StopWatching: notificationType invalid!\n"); 1297eae26d3dSbeveloper return B_BAD_VALUE; 1298eae26d3dSbeveloper } 1299f4925104Sbeveloper return BPrivate::media::notifications::Unregister(where, media_node::null, notificationType); 130052a38012Sejakowatz } 130152a38012Sejakowatz 130252a38012Sejakowatz 130352a38012Sejakowatz status_t 130452a38012Sejakowatz BMediaRoster::StopWatching(const BMessenger & where, 130552a38012Sejakowatz const media_node & node, 130652a38012Sejakowatz int32 notificationType) 130752a38012Sejakowatz { 1308eae26d3dSbeveloper CALLED(); 1309eae26d3dSbeveloper // messenger may already be invalid, so we don't check this 13109e9417d2Sbeveloper if (node.node <= 0) { 1311353b9f6bSbeveloper FATAL("BMediaRoster::StopWatching: node invalid!\n"); 1312eae26d3dSbeveloper return B_MEDIA_BAD_NODE; 1313eae26d3dSbeveloper } 1314f4925104Sbeveloper if (false == BPrivate::media::notifications::IsValidNotificationRequest(true, notificationType)) { 1315353b9f6bSbeveloper FATAL("BMediaRoster::StopWatching: notificationType invalid!\n"); 1316eae26d3dSbeveloper return B_BAD_VALUE; 1317eae26d3dSbeveloper } 1318f4925104Sbeveloper return BPrivate::media::notifications::Unregister(where, node, notificationType); 131952a38012Sejakowatz } 132052a38012Sejakowatz 132152a38012Sejakowatz 132252a38012Sejakowatz status_t 132352a38012Sejakowatz BMediaRoster::RegisterNode(BMediaNode * node) 132452a38012Sejakowatz { 132552a38012Sejakowatz CALLED(); 132652a38012Sejakowatz if (node == NULL) 132752a38012Sejakowatz return B_BAD_VALUE; 132852a38012Sejakowatz 13293620737cSbeveloper status_t rv; 13309e9417d2Sbeveloper BMediaAddOn *addon; 13319e9417d2Sbeveloper int32 addon_flavor_id; 13329e9417d2Sbeveloper media_addon_id addon_id; 13333620737cSbeveloper 13349e9417d2Sbeveloper addon_flavor_id = 0; 13359e9417d2Sbeveloper addon = node->AddOn(&addon_flavor_id); 13369e9417d2Sbeveloper addon_id = addon ? addon->AddonID() : -1; 133752a38012Sejakowatz 13389e9417d2Sbeveloper server_register_node_request request; 13399e9417d2Sbeveloper server_register_node_reply reply; 13409e9417d2Sbeveloper 13419e9417d2Sbeveloper request.addon_id = addon_id; 13429e9417d2Sbeveloper request.addon_flavor_id = addon_flavor_id; 13439e9417d2Sbeveloper strcpy(request.name, node->Name()); 13449e9417d2Sbeveloper request.kinds = node->Kinds(); 13459e9417d2Sbeveloper request.port = node->ControlPort(); 13469e9417d2Sbeveloper request.team = team; 13479e9417d2Sbeveloper 13481299bfb2Sbeveloper TRACE("BMediaRoster::RegisterNode: sending SERVER_REGISTER_NODE: port %ld, kinds %#Lx, team %ld, name '%s'\n", request.port, request.kinds, request.team, request.name); 13491299bfb2Sbeveloper 13509e9417d2Sbeveloper rv = QueryServer(SERVER_REGISTER_NODE, &request, sizeof(request), &reply, sizeof(reply)); 13519e9417d2Sbeveloper if (rv != B_OK) { 1352353b9f6bSbeveloper FATAL("BMediaRoster::RegisterNode: failed to register node %s (error %#lx)\n", node->Name(), rv); 13539e9417d2Sbeveloper return rv; 13549e9417d2Sbeveloper } 13559e9417d2Sbeveloper 13569e9417d2Sbeveloper // we are a friend class of BMediaNode and initilize this member variable 13579e9417d2Sbeveloper node->fNodeID = reply.nodeid; 13589e9417d2Sbeveloper ASSERT(reply.nodeid == node->Node().node); 13599e9417d2Sbeveloper ASSERT(reply.nodeid == node->ID()); 13609e9417d2Sbeveloper 13619e9417d2Sbeveloper // call the callback 13629e9417d2Sbeveloper node->NodeRegistered(); 13633620737cSbeveloper 1364*0e21b167Sbeveloper // if the BMediaNode also inherits from BTimeSource, we need to call BTimeSource::FinishCreate() 1365*0e21b167Sbeveloper if (node->Kinds() & B_TIME_SOURCE) { 1366*0e21b167Sbeveloper BTimeSource *ts; 1367*0e21b167Sbeveloper ts = dynamic_cast<BTimeSource *>(node); 1368*0e21b167Sbeveloper if (ts) 1369*0e21b167Sbeveloper ts->FinishCreate(); 1370*0e21b167Sbeveloper } 1371*0e21b167Sbeveloper 1372570f7d04Sbeveloper /* 13733620737cSbeveloper // register existing inputs and outputs with the 13743620737cSbeveloper // media_server, this allows GetLiveNodes() to work 13753620737cSbeveloper // with created, but unconnected nodes. 13763620737cSbeveloper if (node->Kinds() & B_BUFFER_PRODUCER) { 13773620737cSbeveloper Stack<media_output> stack; 13783620737cSbeveloper if (B_OK == GetAllOutputs(node->Node(), &stack)) 13793620737cSbeveloper PublishOutputs(node->Node(), &stack); 13803620737cSbeveloper } else if (node->Kinds() & B_BUFFER_CONSUMER) { 13813620737cSbeveloper Stack<media_input> stack; 13823620737cSbeveloper if (B_OK == GetAllInputs(node->Node(), &stack)) 13833620737cSbeveloper PublishInputs(node->Node(), &stack); 13843620737cSbeveloper } 1385570f7d04Sbeveloper */ 1386570f7d04Sbeveloper 13871299bfb2Sbeveloper BPrivate::media::notifications::NodesCreated(&reply.nodeid, 1); 1388570f7d04Sbeveloper /* 1389570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: registered node name '%s', id %ld, addon %ld, flavor %ld\n", node->Name(), node->ID(), addon_id, addon_flavor_id); 1390570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node this %p\n", node); 1391570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node fConsumerThis %p\n", node->fConsumerThis); 1392570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node fProducerThis %p\n", node->fProducerThis); 1393570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node fFileInterfaceThis %p\n", node->fFileInterfaceThis); 1394570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node fControllableThis %p\n", node->fControllableThis); 1395570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node fTimeSourceThis %p\n", node->fTimeSourceThis); 1396570f7d04Sbeveloper */ 13979e9417d2Sbeveloper 13989e9417d2Sbeveloper return B_OK; 139952a38012Sejakowatz } 140052a38012Sejakowatz 140152a38012Sejakowatz 140252a38012Sejakowatz status_t 140352a38012Sejakowatz BMediaRoster::UnregisterNode(BMediaNode * node) 140452a38012Sejakowatz { 14059e9417d2Sbeveloper CALLED(); 14069e9417d2Sbeveloper if (node == NULL) 14079e9417d2Sbeveloper return B_BAD_VALUE; 14089e9417d2Sbeveloper 14099e9417d2Sbeveloper if (node->fRefCount != 0) { 1410353b9f6bSbeveloper FATAL("BMediaRoster::UnregisterNode: Warning node name '%s' has local reference count of %ld\n", node->Name(), node->fRefCount); 14119e9417d2Sbeveloper // no return here, we continue and unregister! 14129e9417d2Sbeveloper } 14139e9417d2Sbeveloper if (node->ID() == -2) { 1414353b9f6bSbeveloper FATAL("BMediaRoster::UnregisterNode: Warning node name '%s' already unregistered\n", node->Name()); 14159e9417d2Sbeveloper return B_OK; 14169e9417d2Sbeveloper } 14179e9417d2Sbeveloper 14189e9417d2Sbeveloper server_unregister_node_request request; 14199e9417d2Sbeveloper server_unregister_node_reply reply; 14209e9417d2Sbeveloper status_t rv; 14219e9417d2Sbeveloper 14229e9417d2Sbeveloper request.nodeid = node->ID(); 14239e9417d2Sbeveloper request.team = team; 14249e9417d2Sbeveloper 14251299bfb2Sbeveloper // send a notification 14261299bfb2Sbeveloper BPrivate::media::notifications::NodesDeleted(&request.nodeid, 1); 14271299bfb2Sbeveloper 14289e9417d2Sbeveloper rv = QueryServer(SERVER_UNREGISTER_NODE, &request, sizeof(request), &reply, sizeof(reply)); 14299e9417d2Sbeveloper if (rv != B_OK) { 1430353b9f6bSbeveloper FATAL("BMediaRoster::UnregisterNode: failed to unregister node name '%s' (error %#lx)\n", node->Name(), rv); 14319e9417d2Sbeveloper return rv; 14329e9417d2Sbeveloper } 14339e9417d2Sbeveloper 14349e9417d2Sbeveloper if (reply.addon_id != -1) 14359e9417d2Sbeveloper _DormantNodeManager->PutAddon(reply.addon_id); 14369e9417d2Sbeveloper 14371299bfb2Sbeveloper // we are a friend class of BMediaNode and invalidate this member variable 14389e9417d2Sbeveloper node->fNodeID = -2; 14399e9417d2Sbeveloper 14409e9417d2Sbeveloper return B_OK; 144152a38012Sejakowatz } 144252a38012Sejakowatz 144352a38012Sejakowatz 144452a38012Sejakowatz // thread safe for multiple calls to Roster() 144552a38012Sejakowatz /* static */ BMediaRoster * 144652a38012Sejakowatz BMediaRoster::Roster(status_t* out_error) 144752a38012Sejakowatz { 144852a38012Sejakowatz static BLocker locker("BMediaRoster::Roster locker"); 144952a38012Sejakowatz locker.Lock(); 145052a38012Sejakowatz if (_sDefault == NULL) { 145152a38012Sejakowatz _sDefault = new BMediaRoster(); 145252a38012Sejakowatz if (out_error != NULL) 145352a38012Sejakowatz *out_error = B_OK; 145452a38012Sejakowatz } else { 145552a38012Sejakowatz if (out_error != NULL) 145652a38012Sejakowatz *out_error = B_OK; 145752a38012Sejakowatz } 145852a38012Sejakowatz locker.Unlock(); 145952a38012Sejakowatz return _sDefault; 146052a38012Sejakowatz } 146152a38012Sejakowatz 146252a38012Sejakowatz 146352a38012Sejakowatz // won't create it if there isn't one 146452a38012Sejakowatz // not thread safe if you call Roster() at the same time 146552a38012Sejakowatz /* static */ BMediaRoster * 146652a38012Sejakowatz BMediaRoster::CurrentRoster() 146752a38012Sejakowatz { 146852a38012Sejakowatz return _sDefault; 146952a38012Sejakowatz } 147052a38012Sejakowatz 147152a38012Sejakowatz 147252a38012Sejakowatz status_t 147352a38012Sejakowatz BMediaRoster::SetTimeSourceFor(media_node_id node, 147452a38012Sejakowatz media_node_id time_source) 147552a38012Sejakowatz { 1476aac800c2Sbeveloper CALLED(); 1477aac800c2Sbeveloper if (node <= 0 || time_source <= 0) 1478aac800c2Sbeveloper return B_BAD_VALUE; 1479aac800c2Sbeveloper 1480aac800c2Sbeveloper media_node clone; 1481aac800c2Sbeveloper status_t rv, result; 1482aac800c2Sbeveloper 1483aac800c2Sbeveloper rv = GetNodeFor(node, &clone); 1484aac800c2Sbeveloper if (rv != B_OK) { 1485aac800c2Sbeveloper FATAL("BMediaRoster::SetTimeSourceFor, GetNodeFor failed, node id %ld\n", node); 148652a38012Sejakowatz return B_ERROR; 148752a38012Sejakowatz } 148852a38012Sejakowatz 1489aac800c2Sbeveloper result = B_OK; 1490aac800c2Sbeveloper node_set_timesource_command cmd; 1491aac800c2Sbeveloper cmd.timesource_id = time_source; 1492aac800c2Sbeveloper rv = SendToPort(clone.port, NODE_SET_TIMESOURCE, &cmd, sizeof(cmd)); 1493aac800c2Sbeveloper if (rv != B_OK) { 1494aac800c2Sbeveloper FATAL("BMediaRoster::SetTimeSourceFor, sending NODE_SET_TIMESOURCE failed, node id %ld\n", node); 1495aac800c2Sbeveloper result = B_ERROR; 1496aac800c2Sbeveloper } 1497aac800c2Sbeveloper 1498aac800c2Sbeveloper rv = ReleaseNode(clone); 1499aac800c2Sbeveloper if (rv != B_OK) { 1500aac800c2Sbeveloper FATAL("BMediaRoster::SetTimeSourceFor, ReleaseNode failed, node id %ld\n", node); 1501aac800c2Sbeveloper result = B_ERROR; 1502aac800c2Sbeveloper } 1503aac800c2Sbeveloper 1504aac800c2Sbeveloper return result; 1505aac800c2Sbeveloper } 1506aac800c2Sbeveloper 150752a38012Sejakowatz 150852a38012Sejakowatz status_t 150952a38012Sejakowatz BMediaRoster::GetParameterWebFor(const media_node & node, 151052a38012Sejakowatz BParameterWeb ** out_web) 151152a38012Sejakowatz { 151252a38012Sejakowatz UNIMPLEMENTED(); 151352a38012Sejakowatz return B_ERROR; 151452a38012Sejakowatz } 151552a38012Sejakowatz 151652a38012Sejakowatz 151752a38012Sejakowatz status_t 151852a38012Sejakowatz BMediaRoster::StartControlPanel(const media_node & node, 151952a38012Sejakowatz BMessenger * out_messenger) 152052a38012Sejakowatz { 152152a38012Sejakowatz UNIMPLEMENTED(); 152252a38012Sejakowatz return B_ERROR; 152352a38012Sejakowatz } 152452a38012Sejakowatz 152552a38012Sejakowatz 152652a38012Sejakowatz status_t 152752a38012Sejakowatz BMediaRoster::GetDormantNodes(dormant_node_info * out_info, 152852a38012Sejakowatz int32 * io_count, 152952a38012Sejakowatz const media_format * has_input /* = NULL */, 153052a38012Sejakowatz const media_format * has_output /* = NULL */, 153152a38012Sejakowatz const char * name /* = NULL */, 153252a38012Sejakowatz uint64 require_kinds /* = NULL */, 153352a38012Sejakowatz uint64 deny_kinds /* = NULL */) 153452a38012Sejakowatz { 153552a38012Sejakowatz CALLED(); 153652a38012Sejakowatz if (out_info == NULL) 153752a38012Sejakowatz return B_BAD_VALUE; 153852a38012Sejakowatz if (io_count == NULL) 153952a38012Sejakowatz return B_BAD_VALUE; 154052a38012Sejakowatz if (*io_count <= 0) 154152a38012Sejakowatz return B_BAD_VALUE; 154252a38012Sejakowatz 154352a38012Sejakowatz xfer_server_get_dormant_nodes msg; 154452a38012Sejakowatz port_id port; 154552a38012Sejakowatz status_t rv; 154652a38012Sejakowatz 154752a38012Sejakowatz port = find_port("media_server port"); 154852a38012Sejakowatz if (port <= B_OK) 154952a38012Sejakowatz return B_ERROR; 155052a38012Sejakowatz 155152a38012Sejakowatz msg.maxcount = *io_count; 155252a38012Sejakowatz msg.has_input = (bool) has_input; 155352a38012Sejakowatz if (has_input) 155452a38012Sejakowatz msg.inputformat = *has_input; // XXX we should not make a flat copy of media_format 155552a38012Sejakowatz msg.has_output = (bool) has_output; 155652a38012Sejakowatz if (has_output) 155752a38012Sejakowatz msg.outputformat = *has_output;; // XXX we should not make a flat copy of media_format 155852a38012Sejakowatz msg.has_name = (bool) name; 155952a38012Sejakowatz if (name) { 15609e9417d2Sbeveloper int len = strlen(name); 15619e9417d2Sbeveloper len = min_c(len, (int)sizeof(msg.name) - 1); 156252a38012Sejakowatz memcpy(msg.name, name, len); 156352a38012Sejakowatz msg.name[len] = 0; 156452a38012Sejakowatz } 156552a38012Sejakowatz msg.require_kinds = require_kinds; 156652a38012Sejakowatz msg.deny_kinds = deny_kinds; 156752a38012Sejakowatz msg.reply_port = _PortPool->GetPort(); 156852a38012Sejakowatz 156952a38012Sejakowatz rv = write_port(port, SERVER_GET_DORMANT_NODES, &msg, sizeof(msg)); 157052a38012Sejakowatz if (rv != B_OK) { 157152a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 157252a38012Sejakowatz return rv; 157352a38012Sejakowatz } 157452a38012Sejakowatz 157552a38012Sejakowatz xfer_server_get_dormant_nodes_reply reply; 157652a38012Sejakowatz int32 code; 157752a38012Sejakowatz 157852a38012Sejakowatz rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); 157952a38012Sejakowatz if (rv < B_OK) { 158052a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 158152a38012Sejakowatz return rv; 158252a38012Sejakowatz } 158352a38012Sejakowatz 158452a38012Sejakowatz *io_count = reply.count; 158552a38012Sejakowatz 158652a38012Sejakowatz if (*io_count > 0) { 158752a38012Sejakowatz rv = read_port(msg.reply_port, &code, out_info, *io_count * sizeof(dormant_node_info)); 158852a38012Sejakowatz if (rv < B_OK) 158952a38012Sejakowatz reply.result = rv; 159052a38012Sejakowatz } 159152a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 159252a38012Sejakowatz 159352a38012Sejakowatz return reply.result; 159452a38012Sejakowatz } 159552a38012Sejakowatz 159652a38012Sejakowatz 159752a38012Sejakowatz status_t 159852a38012Sejakowatz BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info, 159952a38012Sejakowatz media_node * out_node, 160052a38012Sejakowatz uint32 flags /* currently B_FLAVOR_IS_GLOBAL or B_FLAVOR_IS_LOCAL */ ) 160152a38012Sejakowatz { 160252a38012Sejakowatz CALLED(); 160352a38012Sejakowatz if ((flags & (B_FLAVOR_IS_GLOBAL | B_FLAVOR_IS_LOCAL)) == 0) { 1604618b1338Sbeveloper FATAL("Error: BMediaRoster::InstantiateDormantNode called without valid flags\n"); 160552a38012Sejakowatz return B_BAD_VALUE; 160652a38012Sejakowatz } 160752a38012Sejakowatz if (out_node == 0) 160852a38012Sejakowatz return B_BAD_VALUE; 160952a38012Sejakowatz 161052a38012Sejakowatz // XXX we should not trust the values passed in by the user, 161152a38012Sejakowatz // XXX and ask the server to determine where to insta 161252a38012Sejakowatz 1613e0207628Sbeveloper 1614e0207628Sbeveloper // XXX SOMETHING IS VERY WRONG HERE 1615e0207628Sbeveloper // if ((in_info.flavor_flags & B_FLAVOR_IS_GLOBAL) == 0 && (flags & B_FLAVOR_IS_LOCAL)) { 1616e0207628Sbeveloper if (flags & B_FLAVOR_IS_LOCAL) { 161752a38012Sejakowatz return InstantiateDormantNode(in_info,out_node); 161852a38012Sejakowatz } 161952a38012Sejakowatz 1620e0207628Sbeveloper // XXX SOMETHING IS VERY WRONG HERE 1621e0207628Sbeveloper // if ((in_info.flavor_flags & B_FLAVOR_IS_GLOBAL) || (flags & B_FLAVOR_IS_GLOBAL)) { 1622e0207628Sbeveloper if (flags & B_FLAVOR_IS_GLOBAL) { 162352a38012Sejakowatz // forward this request into the media_addon_server, 162452a38012Sejakowatz // which in turn will call InstantiateDormantNode() 162552a38012Sejakowatz // to create it there localy 16268c6a6096Sbeveloper addonserver_instantiate_dormant_node_request request; 16278c6a6096Sbeveloper addonserver_instantiate_dormant_node_reply reply; 162852a38012Sejakowatz status_t rv; 1629f4925104Sbeveloper 1630f4925104Sbeveloper request.info = in_info; 1631f4925104Sbeveloper rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request, sizeof(request), &reply, sizeof(reply)); 1632f4925104Sbeveloper if (rv == B_OK) { 163352a38012Sejakowatz *out_node = reply.node; 1634f4925104Sbeveloper } 1635f4925104Sbeveloper return rv; 163652a38012Sejakowatz } 163752a38012Sejakowatz 1638e0207628Sbeveloper // XXX SOMETHING IS VERY WRONG HERE 1639618b1338Sbeveloper FATAL("Error: BMediaRoster::InstantiateDormantNode addon_id %d, flavor_id %d, flags %#08lx\n", (int)in_info.addon, (int)in_info.flavor_id, flags); 164052a38012Sejakowatz 164152a38012Sejakowatz return B_ERROR; 164252a38012Sejakowatz } 164352a38012Sejakowatz 164452a38012Sejakowatz 164552a38012Sejakowatz status_t 164652a38012Sejakowatz BMediaRoster::InstantiateDormantNode(const dormant_node_info & in_info, 164752a38012Sejakowatz media_node * out_node) 164852a38012Sejakowatz { 164916b7eea4Sbeveloper CALLED(); 165052a38012Sejakowatz 165152a38012Sejakowatz // to instantiate a dormant node in the current address space, we need to 165252a38012Sejakowatz // either load the add-on from file and create a new BMediaAddOn class, or 165352a38012Sejakowatz // reuse the cached BMediaAddOn from a previous call 165452a38012Sejakowatz // call BMediaAddOn::InstantiateNodeFor() 165552a38012Sejakowatz // and cache the BMediaAddOn after that for later reuse. 165652a38012Sejakowatz // BeOS R5 does not seem to delete it when the application quits 165752a38012Sejakowatz // if B_FLAVOR_IS_GLOBAL, we need to use the BMediaAddOn object that 165852a38012Sejakowatz // resides in the media_addon_server 165952a38012Sejakowatz 166052a38012Sejakowatz // RegisterNode() is called automatically for nodes instantiated from add-ons 166152a38012Sejakowatz 166216b7eea4Sbeveloper //XXX TEST! 166316b7eea4Sbeveloper BMediaAddOn *addon; 166416b7eea4Sbeveloper BMediaNode *node; 166516b7eea4Sbeveloper BMessage config; 166616b7eea4Sbeveloper status_t out_error; 16678c6a6096Sbeveloper status_t rv; 166816b7eea4Sbeveloper addon = _DormantNodeManager->GetAddon(in_info.addon); 166916b7eea4Sbeveloper if (!addon) { 1670618b1338Sbeveloper FATAL("BMediaRoster::InstantiateDormantNode: GetAddon failed\n"); 167152a38012Sejakowatz return B_ERROR; 167252a38012Sejakowatz } 16731299bfb2Sbeveloper flavor_info temp; // XXX fix this! 16741299bfb2Sbeveloper temp.name = "XXX flavor_info name"; 16751299bfb2Sbeveloper temp.info = "XXX flavor_info info"; 167616b7eea4Sbeveloper temp.internal_id = in_info.flavor_id; 167716b7eea4Sbeveloper node = addon->InstantiateNodeFor(&temp, &config, &out_error); 167816b7eea4Sbeveloper if (!node) { 1679618b1338Sbeveloper FATAL("BMediaRoster::InstantiateDormantNode: InstantiateNodeFor failed\n"); 168016b7eea4Sbeveloper _DormantNodeManager->PutAddon(in_info.addon); 168116b7eea4Sbeveloper return B_ERROR; 168216b7eea4Sbeveloper } 16838c6a6096Sbeveloper rv = RegisterNode(node); 16848c6a6096Sbeveloper if (rv != B_OK) { 1685618b1338Sbeveloper FATAL("BMediaRoster::InstantiateDormantNode: RegisterNode failed\n"); 16868c6a6096Sbeveloper delete node; 16878c6a6096Sbeveloper _DormantNodeManager->PutAddon(in_info.addon); 16888c6a6096Sbeveloper return B_ERROR; 16898c6a6096Sbeveloper } 16908c6a6096Sbeveloper 16918c6a6096Sbeveloper // XXX we must remember in_info.addon and call 16928c6a6096Sbeveloper // XXX _DormantNodeManager->PutAddon when the 16938c6a6096Sbeveloper // XXX node is unregistered 16949e9417d2Sbeveloper // should be handled by RegisterNode() and UnegisterNode() now 16958c6a6096Sbeveloper 169616b7eea4Sbeveloper *out_node = node->Node(); 169716b7eea4Sbeveloper return B_OK; 169816b7eea4Sbeveloper } 169952a38012Sejakowatz 170052a38012Sejakowatz 170152a38012Sejakowatz status_t 170252a38012Sejakowatz BMediaRoster::GetDormantNodeFor(const media_node & node, 170352a38012Sejakowatz dormant_node_info * out_info) 170452a38012Sejakowatz { 170585dfab2bSbeveloper CALLED(); 170685dfab2bSbeveloper if (out_info == NULL) 170785dfab2bSbeveloper return B_BAD_VALUE; 170885dfab2bSbeveloper if (node.node <= 0) 170985dfab2bSbeveloper return B_MEDIA_BAD_NODE; 171052a38012Sejakowatz 171185dfab2bSbeveloper server_get_dormant_node_for_request request; 171285dfab2bSbeveloper server_get_dormant_node_for_reply reply; 171385dfab2bSbeveloper status_t rv; 171485dfab2bSbeveloper 171585dfab2bSbeveloper request.node = node; 171685dfab2bSbeveloper 17171299bfb2Sbeveloper rv = QueryServer(SERVER_GET_DORMANT_NODE_FOR, &request, sizeof(request), &reply, sizeof(reply)); 171885dfab2bSbeveloper if (rv != B_OK) 171985dfab2bSbeveloper return rv; 172085dfab2bSbeveloper 172185dfab2bSbeveloper *out_info = reply.node_info; 172285dfab2bSbeveloper return B_OK; 172352a38012Sejakowatz } 172452a38012Sejakowatz 172552a38012Sejakowatz 172652a38012Sejakowatz status_t 172752a38012Sejakowatz BMediaRoster::GetDormantFlavorInfoFor(const dormant_node_info & in_dormant, 172852a38012Sejakowatz dormant_flavor_info * out_flavor) 172952a38012Sejakowatz { 173052a38012Sejakowatz CALLED(); 173152a38012Sejakowatz 173252a38012Sejakowatz xfer_server_get_dormant_flavor_info msg; 173352a38012Sejakowatz xfer_server_get_dormant_flavor_info_reply *reply; 173452a38012Sejakowatz port_id port; 173552a38012Sejakowatz status_t rv; 173652a38012Sejakowatz int32 code; 173752a38012Sejakowatz 173852a38012Sejakowatz port = find_port("media_server port"); 173952a38012Sejakowatz if (port <= B_OK) 174052a38012Sejakowatz return B_ERROR; 174152a38012Sejakowatz 174252a38012Sejakowatz reply = (xfer_server_get_dormant_flavor_info_reply *) malloc(16000); 174352a38012Sejakowatz if (reply == 0) 174452a38012Sejakowatz return B_ERROR; 174552a38012Sejakowatz 174652a38012Sejakowatz msg.addon = in_dormant.addon; 174752a38012Sejakowatz msg.flavor_id = in_dormant.flavor_id; 174852a38012Sejakowatz msg.reply_port = _PortPool->GetPort(); 174952a38012Sejakowatz rv = write_port(port, SERVER_GET_DORMANT_FLAVOR_INFO, &msg, sizeof(msg)); 175052a38012Sejakowatz if (rv != B_OK) { 175152a38012Sejakowatz free(reply); 175252a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 175352a38012Sejakowatz return rv; 175452a38012Sejakowatz } 175552a38012Sejakowatz rv = read_port(msg.reply_port, &code, reply, 16000); 175652a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 175752a38012Sejakowatz 175852a38012Sejakowatz if (rv < B_OK) { 175952a38012Sejakowatz free(reply); 176052a38012Sejakowatz return rv; 176152a38012Sejakowatz } 176252a38012Sejakowatz 176352a38012Sejakowatz if (reply->result == B_OK) 176452a38012Sejakowatz rv = out_flavor->Unflatten(reply->dfi_type, &reply->dfi, reply->dfi_size); 176552a38012Sejakowatz else 176652a38012Sejakowatz rv = reply->result; 176752a38012Sejakowatz 176852a38012Sejakowatz free(reply); 176952a38012Sejakowatz return rv; 177052a38012Sejakowatz } 177152a38012Sejakowatz 177252a38012Sejakowatz 177352a38012Sejakowatz status_t 177452a38012Sejakowatz BMediaRoster::GetLatencyFor(const media_node & producer, 177552a38012Sejakowatz bigtime_t * out_latency) 177652a38012Sejakowatz { 177752a38012Sejakowatz UNIMPLEMENTED(); 1778*0e21b167Sbeveloper *out_latency = 2000; 1779aac800c2Sbeveloper return B_OK; 178052a38012Sejakowatz } 178152a38012Sejakowatz 178252a38012Sejakowatz 178352a38012Sejakowatz status_t 178452a38012Sejakowatz BMediaRoster::GetInitialLatencyFor(const media_node & producer, 178552a38012Sejakowatz bigtime_t * out_latency, 1786aac800c2Sbeveloper uint32 * out_flags /* = NULL */) 178752a38012Sejakowatz { 178852a38012Sejakowatz UNIMPLEMENTED(); 1789*0e21b167Sbeveloper *out_latency = 1000; 1790aac800c2Sbeveloper if (out_flags) 179152a38012Sejakowatz *out_flags = 0; 1792aac800c2Sbeveloper return B_OK; 179352a38012Sejakowatz } 179452a38012Sejakowatz 179552a38012Sejakowatz 179652a38012Sejakowatz status_t 179752a38012Sejakowatz BMediaRoster::GetStartLatencyFor(const media_node & time_source, 179852a38012Sejakowatz bigtime_t * out_latency) 179952a38012Sejakowatz { 180052a38012Sejakowatz UNIMPLEMENTED(); 1801aac800c2Sbeveloper *out_latency = 5000; 1802aac800c2Sbeveloper return B_OK; 180352a38012Sejakowatz } 180452a38012Sejakowatz 180552a38012Sejakowatz 180652a38012Sejakowatz status_t 180752a38012Sejakowatz BMediaRoster::GetFileFormatsFor(const media_node & file_interface, 180852a38012Sejakowatz media_file_format * out_formats, 180952a38012Sejakowatz int32 * io_num_infos) 181052a38012Sejakowatz { 181152a38012Sejakowatz UNIMPLEMENTED(); 181252a38012Sejakowatz return B_ERROR; 181352a38012Sejakowatz } 181452a38012Sejakowatz 181552a38012Sejakowatz 181652a38012Sejakowatz status_t 181752a38012Sejakowatz BMediaRoster::SetRefFor(const media_node & file_interface, 181852a38012Sejakowatz const entry_ref & file, 181952a38012Sejakowatz bool create_and_truncate, 182052a38012Sejakowatz bigtime_t * out_length) /* if create is false */ 182152a38012Sejakowatz { 182252a38012Sejakowatz UNIMPLEMENTED(); 182352a38012Sejakowatz return B_ERROR; 182452a38012Sejakowatz } 182552a38012Sejakowatz 182652a38012Sejakowatz 182752a38012Sejakowatz status_t 182852a38012Sejakowatz BMediaRoster::GetRefFor(const media_node & node, 182952a38012Sejakowatz entry_ref * out_file, 183052a38012Sejakowatz BMimeType * mime_type) 183152a38012Sejakowatz { 183252a38012Sejakowatz UNIMPLEMENTED(); 183352a38012Sejakowatz return B_ERROR; 183452a38012Sejakowatz } 183552a38012Sejakowatz 183652a38012Sejakowatz 183752a38012Sejakowatz status_t 183852a38012Sejakowatz BMediaRoster::SniffRefFor(const media_node & file_interface, 183952a38012Sejakowatz const entry_ref & file, 184052a38012Sejakowatz BMimeType * mime_type, 184152a38012Sejakowatz float * out_capability) 184252a38012Sejakowatz { 184352a38012Sejakowatz UNIMPLEMENTED(); 184452a38012Sejakowatz return B_ERROR; 184552a38012Sejakowatz } 184652a38012Sejakowatz 184752a38012Sejakowatz 184852a38012Sejakowatz /* This is the generic "here's a file, now can someone please play it" interface */ 184952a38012Sejakowatz status_t 185052a38012Sejakowatz BMediaRoster::SniffRef(const entry_ref & file, 185152a38012Sejakowatz uint64 require_node_kinds, /* if you need an EntityInterface or BufferConsumer or something */ 185252a38012Sejakowatz dormant_node_info * out_node, 185352a38012Sejakowatz BMimeType * mime_type) 185452a38012Sejakowatz { 185552a38012Sejakowatz UNIMPLEMENTED(); 185652a38012Sejakowatz return B_ERROR; 185752a38012Sejakowatz } 185852a38012Sejakowatz 185952a38012Sejakowatz 186052a38012Sejakowatz status_t 186152a38012Sejakowatz BMediaRoster::GetDormantNodeForType(const BMimeType & type, 186252a38012Sejakowatz uint64 require_node_kinds, 186352a38012Sejakowatz dormant_node_info * out_node) 186452a38012Sejakowatz { 186552a38012Sejakowatz UNIMPLEMENTED(); 186652a38012Sejakowatz return B_ERROR; 186752a38012Sejakowatz } 186852a38012Sejakowatz 186952a38012Sejakowatz 187052a38012Sejakowatz status_t 187152a38012Sejakowatz BMediaRoster::GetReadFileFormatsFor(const dormant_node_info & in_node, 187252a38012Sejakowatz media_file_format * out_read_formats, 187352a38012Sejakowatz int32 in_read_count, 187452a38012Sejakowatz int32 * out_read_count) 187552a38012Sejakowatz { 187652a38012Sejakowatz UNIMPLEMENTED(); 187752a38012Sejakowatz return B_ERROR; 187852a38012Sejakowatz } 187952a38012Sejakowatz 188052a38012Sejakowatz 188152a38012Sejakowatz status_t 188252a38012Sejakowatz BMediaRoster::GetWriteFileFormatsFor(const dormant_node_info & in_node, 188352a38012Sejakowatz media_file_format * out_write_formats, 188452a38012Sejakowatz int32 in_write_count, 188552a38012Sejakowatz int32 * out_write_count) 188652a38012Sejakowatz { 188752a38012Sejakowatz UNIMPLEMENTED(); 188852a38012Sejakowatz return B_ERROR; 188952a38012Sejakowatz } 189052a38012Sejakowatz 189152a38012Sejakowatz 189252a38012Sejakowatz status_t 189352a38012Sejakowatz BMediaRoster::GetFormatFor(const media_output & output, 189452a38012Sejakowatz media_format * io_format, 189552a38012Sejakowatz uint32 flags) 189652a38012Sejakowatz { 189752a38012Sejakowatz UNIMPLEMENTED(); 189852a38012Sejakowatz return B_ERROR; 189952a38012Sejakowatz } 190052a38012Sejakowatz 190152a38012Sejakowatz 190252a38012Sejakowatz status_t 190352a38012Sejakowatz BMediaRoster::GetFormatFor(const media_input & input, 190452a38012Sejakowatz media_format * io_format, 190552a38012Sejakowatz uint32 flags) 190652a38012Sejakowatz { 190752a38012Sejakowatz UNIMPLEMENTED(); 190852a38012Sejakowatz return B_ERROR; 190952a38012Sejakowatz } 191052a38012Sejakowatz 191152a38012Sejakowatz 191252a38012Sejakowatz status_t 191352a38012Sejakowatz BMediaRoster::GetFormatFor(const media_node & node, 191452a38012Sejakowatz media_format * io_format, 191552a38012Sejakowatz float quality) 191652a38012Sejakowatz { 191752a38012Sejakowatz UNIMPLEMENTED(); 191852a38012Sejakowatz return B_ERROR; 191952a38012Sejakowatz } 192052a38012Sejakowatz 192152a38012Sejakowatz 192252a38012Sejakowatz ssize_t 192352a38012Sejakowatz BMediaRoster::GetNodeAttributesFor(const media_node & node, 192452a38012Sejakowatz media_node_attribute * outArray, 192552a38012Sejakowatz size_t inMaxCount) 192652a38012Sejakowatz { 192752a38012Sejakowatz UNIMPLEMENTED(); 192852a38012Sejakowatz return B_ERROR; 192952a38012Sejakowatz } 193052a38012Sejakowatz 193152a38012Sejakowatz 193252a38012Sejakowatz media_node_id 193352a38012Sejakowatz BMediaRoster::NodeIDFor(port_id source_or_destination_port) 193452a38012Sejakowatz { 19359e9417d2Sbeveloper CALLED(); 19369e9417d2Sbeveloper 19379e9417d2Sbeveloper server_node_id_for_request request; 19389e9417d2Sbeveloper server_node_id_for_reply reply; 19399e9417d2Sbeveloper status_t rv; 19409e9417d2Sbeveloper 19419e9417d2Sbeveloper request.port = source_or_destination_port; 19429e9417d2Sbeveloper 19439e9417d2Sbeveloper rv = QueryServer(SERVER_NODE_ID_FOR, &request, sizeof(request), &reply, sizeof(reply)); 19449e9417d2Sbeveloper if (rv != B_OK) { 1945353b9f6bSbeveloper FATAL("BMediaRoster::NodeIDFor: failed (error %#lx)\n", rv); 19469e9417d2Sbeveloper return -1; 19479e9417d2Sbeveloper } 19489e9417d2Sbeveloper 19499e9417d2Sbeveloper return reply.nodeid; 195052a38012Sejakowatz } 195152a38012Sejakowatz 195252a38012Sejakowatz 195352a38012Sejakowatz status_t 195452a38012Sejakowatz BMediaRoster::GetInstancesFor(media_addon_id addon, 195552a38012Sejakowatz int32 flavor, 195652a38012Sejakowatz media_node_id * out_id, 195752a38012Sejakowatz int32 * io_count) 195852a38012Sejakowatz { 195985dfab2bSbeveloper CALLED(); 196085dfab2bSbeveloper if (out_id == NULL || io_count == NULL) 196185dfab2bSbeveloper return B_BAD_VALUE; 196285dfab2bSbeveloper if (*io_count <= 0) 196385dfab2bSbeveloper return B_BAD_VALUE; 196485dfab2bSbeveloper 196585dfab2bSbeveloper server_get_instances_for_request request; 196685dfab2bSbeveloper server_get_instances_for_reply reply; 196785dfab2bSbeveloper status_t rv; 196885dfab2bSbeveloper 196985dfab2bSbeveloper request.maxcount = *io_count; 197085dfab2bSbeveloper request.addon_id = addon; 197185dfab2bSbeveloper request.addon_flavor_id = flavor; 197285dfab2bSbeveloper 197385dfab2bSbeveloper rv = QueryServer(SERVER_GET_INSTANCES_FOR, &request, sizeof(request), &reply, sizeof(reply)); 197485dfab2bSbeveloper if (rv != B_OK) { 1975353b9f6bSbeveloper FATAL("BMediaRoster::GetLiveNodes failed\n"); 197685dfab2bSbeveloper return rv; 197752a38012Sejakowatz } 197852a38012Sejakowatz 197985dfab2bSbeveloper *io_count = reply.count; 198085dfab2bSbeveloper if (reply.count > 0) 198185dfab2bSbeveloper memcpy(out_id, reply.node_id, sizeof(media_node_id) * reply.count); 198285dfab2bSbeveloper 198385dfab2bSbeveloper return B_OK; 198485dfab2bSbeveloper } 198552a38012Sejakowatz 198652a38012Sejakowatz 198752a38012Sejakowatz status_t 198852a38012Sejakowatz BMediaRoster::SetRealtimeFlags(uint32 in_enabled) 198952a38012Sejakowatz { 199052a38012Sejakowatz UNIMPLEMENTED(); 199152a38012Sejakowatz return B_ERROR; 199252a38012Sejakowatz } 199352a38012Sejakowatz 199452a38012Sejakowatz 199552a38012Sejakowatz status_t 199652a38012Sejakowatz BMediaRoster::GetRealtimeFlags(uint32 * out_enabled) 199752a38012Sejakowatz { 199852a38012Sejakowatz UNIMPLEMENTED(); 199952a38012Sejakowatz return B_ERROR; 200052a38012Sejakowatz } 200152a38012Sejakowatz 200252a38012Sejakowatz 200352a38012Sejakowatz ssize_t 200452a38012Sejakowatz BMediaRoster::AudioBufferSizeFor(int32 channel_count, 200552a38012Sejakowatz uint32 sample_format, 200652a38012Sejakowatz float frame_rate, 200752a38012Sejakowatz bus_type bus_kind) 200852a38012Sejakowatz { 200952a38012Sejakowatz UNIMPLEMENTED(); 201052a38012Sejakowatz return 4096; 201152a38012Sejakowatz } 201252a38012Sejakowatz 201352a38012Sejakowatz 201452a38012Sejakowatz /* Use MediaFlags to inquire about specific features of the Media Kit. */ 201552a38012Sejakowatz /* Returns < 0 for "not present", positive size for output data size. */ 201652a38012Sejakowatz /* 0 means that the capability is present, but no data about it. */ 201752a38012Sejakowatz /* static */ ssize_t 201852a38012Sejakowatz BMediaRoster::MediaFlags(media_flags cap, 201952a38012Sejakowatz void * buf, 202052a38012Sejakowatz size_t maxSize) 202152a38012Sejakowatz { 202252a38012Sejakowatz UNIMPLEMENTED(); 202352a38012Sejakowatz return 0; 202452a38012Sejakowatz } 202552a38012Sejakowatz 202652a38012Sejakowatz 202752a38012Sejakowatz /* BLooper overrides */ 202852a38012Sejakowatz /* virtual */ void 202952a38012Sejakowatz BMediaRoster::MessageReceived(BMessage * message) 203052a38012Sejakowatz { 20316396865dSbeveloper // media_server plays ping-pong with the BMediaRosters 20326396865dSbeveloper // to detect dead teams. Normal communication uses ports. 20336396865dSbeveloper static BMessage pong('PONG'); 20346396865dSbeveloper if (message->what == 'PING') { 20356396865dSbeveloper message->SendReply(&pong, static_cast<BHandler *>(NULL), 2000000); 20366396865dSbeveloper return; 20376396865dSbeveloper } 20386396865dSbeveloper 20396396865dSbeveloper printf("BMediaRoster::MessageReceived: unknown message!\n"); 20406396865dSbeveloper message->PrintToStream(); 204152a38012Sejakowatz } 204252a38012Sejakowatz 204352a38012Sejakowatz /* virtual */ bool 204452a38012Sejakowatz BMediaRoster::QuitRequested() 204552a38012Sejakowatz { 204652a38012Sejakowatz UNIMPLEMENTED(); 204752a38012Sejakowatz return true; 204852a38012Sejakowatz } 204952a38012Sejakowatz 205052a38012Sejakowatz /* virtual */ BHandler * 205152a38012Sejakowatz BMediaRoster::ResolveSpecifier(BMessage *msg, 205252a38012Sejakowatz int32 index, 205352a38012Sejakowatz BMessage *specifier, 205452a38012Sejakowatz int32 form, 205552a38012Sejakowatz const char *property) 205652a38012Sejakowatz { 205752a38012Sejakowatz UNIMPLEMENTED(); 205852a38012Sejakowatz return 0; 205952a38012Sejakowatz } 206052a38012Sejakowatz 206152a38012Sejakowatz 206252a38012Sejakowatz /* virtual */ status_t 206352a38012Sejakowatz BMediaRoster::GetSupportedSuites(BMessage *data) 206452a38012Sejakowatz { 206552a38012Sejakowatz UNIMPLEMENTED(); 206652a38012Sejakowatz return B_ERROR; 206752a38012Sejakowatz } 206852a38012Sejakowatz 206952a38012Sejakowatz 207052a38012Sejakowatz BMediaRoster::~BMediaRoster() 207152a38012Sejakowatz { 207252a38012Sejakowatz CALLED(); 20736396865dSbeveloper 20746396865dSbeveloper // unregister this application with the media server 20756396865dSbeveloper server_unregister_app_request request; 20766396865dSbeveloper server_unregister_app_reply reply; 20776396865dSbeveloper request.team = team; 20786396865dSbeveloper QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply, sizeof(reply)); 207952a38012Sejakowatz } 208052a38012Sejakowatz 208152a38012Sejakowatz 208252a38012Sejakowatz /************************************************************* 208352a38012Sejakowatz * private BMediaRoster 208452a38012Sejakowatz *************************************************************/ 208552a38012Sejakowatz 208652a38012Sejakowatz // deprecated call 208752a38012Sejakowatz status_t 208852a38012Sejakowatz BMediaRoster::SetOutputBuffersFor(const media_source & output, 208952a38012Sejakowatz BBufferGroup * group, 209052a38012Sejakowatz bool will_reclaim ) 209152a38012Sejakowatz { 209252a38012Sejakowatz UNIMPLEMENTED(); 20939e9417d2Sbeveloper debugger("BMediaRoster::SetOutputBuffersFor missing\n"); 209452a38012Sejakowatz return B_ERROR; 209552a38012Sejakowatz } 209652a38012Sejakowatz 209752a38012Sejakowatz 209852a38012Sejakowatz /* FBC stuffing (Mmmh, Stuffing!) */ 209952a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_0(void *) { return B_ERROR; } 210052a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_1(void *) { return B_ERROR; } 210152a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_2(void *) { return B_ERROR; } 210252a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_3(void *) { return B_ERROR; } 210352a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_4(void *) { return B_ERROR; } 210452a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_5(void *) { return B_ERROR; } 210552a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_6(void *) { return B_ERROR; } 210652a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_7(void *) { return B_ERROR; } 210752a38012Sejakowatz 210852a38012Sejakowatz 210952a38012Sejakowatz BMediaRoster::BMediaRoster() : 21106396865dSbeveloper BLooper("_BMediaRoster_", B_URGENT_DISPLAY_PRIORITY, B_LOOPER_PORT_DEFAULT_CAPACITY) 211152a38012Sejakowatz { 211252a38012Sejakowatz CALLED(); 21136396865dSbeveloper 21146396865dSbeveloper // start the looper 21156396865dSbeveloper Run(); 21166396865dSbeveloper 21176396865dSbeveloper // register this application with the media server 21186396865dSbeveloper server_register_app_request request; 21196396865dSbeveloper server_register_app_reply reply; 21206396865dSbeveloper request.team = team; 21216396865dSbeveloper request.messenger = BMessenger(NULL, this); 21226396865dSbeveloper QueryServer(SERVER_REGISTER_APP, &request, sizeof(request), &reply, sizeof(reply)); 212352a38012Sejakowatz } 212452a38012Sejakowatz 21256396865dSbeveloper 212652a38012Sejakowatz /* static */ status_t 212752a38012Sejakowatz BMediaRoster::ParseCommand(BMessage & reply) 212852a38012Sejakowatz { 212952a38012Sejakowatz UNIMPLEMENTED(); 213052a38012Sejakowatz return B_ERROR; 213152a38012Sejakowatz } 213252a38012Sejakowatz 213352a38012Sejakowatz 213452a38012Sejakowatz status_t 213552a38012Sejakowatz BMediaRoster::GetDefaultInfo(media_node_id for_default, 213652a38012Sejakowatz BMessage & out_config) 213752a38012Sejakowatz { 213852a38012Sejakowatz UNIMPLEMENTED(); 213952a38012Sejakowatz return B_ERROR; 214052a38012Sejakowatz } 214152a38012Sejakowatz 214252a38012Sejakowatz 214352a38012Sejakowatz 214452a38012Sejakowatz status_t 214552a38012Sejakowatz BMediaRoster::SetRunningDefault(media_node_id for_default, 214652a38012Sejakowatz const media_node & node) 214752a38012Sejakowatz { 214852a38012Sejakowatz UNIMPLEMENTED(); 214952a38012Sejakowatz return B_ERROR; 215052a38012Sejakowatz } 215152a38012Sejakowatz 215252a38012Sejakowatz 215352a38012Sejakowatz /************************************************************* 215452a38012Sejakowatz * static BMediaRoster variables 215552a38012Sejakowatz *************************************************************/ 215652a38012Sejakowatz 215752a38012Sejakowatz bool BMediaRoster::_isMediaServer; 215852a38012Sejakowatz port_id BMediaRoster::_mReplyPort; 215952a38012Sejakowatz int32 BMediaRoster::_mReplyPortRes; 216052a38012Sejakowatz int32 BMediaRoster::_mReplyPortUnavailCount; 216152a38012Sejakowatz BMediaRoster * BMediaRoster::_sDefault = NULL; 216252a38012Sejakowatz 2163