1255a01c7Sbeveloper /* 234c72144SAxel Dörfler * Copyright 2008 Maurice Kalinowski, haiku@kaldience.com 334c72144SAxel Dörfler * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. 434c72144SAxel Dörfler * 534c72144SAxel Dörfler * All rights reserved. Distributed under the terms of the MIT License. 634c72144SAxel Dörfler */ 734c72144SAxel Dörfler 834c72144SAxel Dörfler /* 965b73ae4SMarcus Overhagen * Copyright (c) 2002-2006 Marcus Overhagen <Marcus@Overhagen.de> 10255a01c7Sbeveloper * 11255a01c7Sbeveloper * Permission is hereby granted, free of charge, to any person obtaining 12255a01c7Sbeveloper * a copy of this software and associated documentation files or portions 13255a01c7Sbeveloper * thereof (the "Software"), to deal in the Software without restriction, 14255a01c7Sbeveloper * including without limitation the rights to use, copy, modify, merge, 15255a01c7Sbeveloper * publish, distribute, sublicense, and/or sell copies of the Software, 16255a01c7Sbeveloper * and to permit persons to whom the Software is furnished to do so, subject 17255a01c7Sbeveloper * to the following conditions: 18255a01c7Sbeveloper * 19255a01c7Sbeveloper * * Redistributions of source code must retain the above copyright notice, 20255a01c7Sbeveloper * this list of conditions and the following disclaimer. 21255a01c7Sbeveloper * 22255a01c7Sbeveloper * * Redistributions in binary form must reproduce the above copyright notice 23255a01c7Sbeveloper * in the binary, as well as this list of conditions and the following 24255a01c7Sbeveloper * disclaimer in the documentation and/or other materials provided with 25255a01c7Sbeveloper * the distribution. 26255a01c7Sbeveloper * 27255a01c7Sbeveloper * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 28255a01c7Sbeveloper * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29255a01c7Sbeveloper * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 30255a01c7Sbeveloper * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31255a01c7Sbeveloper * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32255a01c7Sbeveloper * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 33255a01c7Sbeveloper * THE SOFTWARE. 34255a01c7Sbeveloper * 35255a01c7Sbeveloper */ 366938364bSMaurice Kalinowski 37255a01c7Sbeveloper 38255a01c7Sbeveloper /* to comply with the license above, do not remove the following line */ 398b940bb4SStephan Aßmus char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus " 408b940bb4SStephan Aßmus "Overhagen <Marcus@Overhagen.de>"; 41255a01c7Sbeveloper 4231cf24c1SMarcus Overhagen //#define DEBUG 7 4352a38012Sejakowatz #include <MediaRoster.h> 448b940bb4SStephan Aßmus 45a715f908SStephan Aßmus #include <new> 46a715f908SStephan Aßmus 476938364bSMaurice Kalinowski #include <BufferConsumer.h> 486938364bSMaurice Kalinowski #include <BufferProducer.h> 4952a38012Sejakowatz #include <Locker.h> 5052a38012Sejakowatz #include <Message.h> 5152a38012Sejakowatz #include <Messenger.h> 526938364bSMaurice Kalinowski #include <MimeType.h> 5352a38012Sejakowatz #include <OS.h> 546938364bSMaurice Kalinowski #include <ParameterWeb.h> 556938364bSMaurice Kalinowski #include <StopWatch.h> 5652a38012Sejakowatz #include <String.h> 5752a38012Sejakowatz #include <TimeSource.h> 588b940bb4SStephan Aßmus 5952a38012Sejakowatz #include "debug.h" 608b04ffc1Sbeveloper #include "MediaRosterEx.h" 6140f36b03Sbeveloper #include "MediaMisc.h" 6252a38012Sejakowatz #include "PortPool.h" 630a483e72SIngo Weinhold #include "ServerInterface.h" 64f4925104Sbeveloper #include "DataExchange.h" 6516b7eea4Sbeveloper #include "DormantNodeManager.h" 66f4925104Sbeveloper #include "Notifications.h" 67835140c8Sbeveloper #include "TimeSourceObjectManager.h" 6852a38012Sejakowatz 69f4925104Sbeveloper namespace BPrivate { namespace media { 7052a38012Sejakowatz 7152a38012Sejakowatz // the BMediaRoster destructor is private, 7252a38012Sejakowatz // but _DefaultDeleter is a friend class of 7352a38012Sejakowatz // the BMediaRoster an thus can delete it 748b04ffc1Sbeveloper class DefaultDeleter 7552a38012Sejakowatz { 7652a38012Sejakowatz public: 778b04ffc1Sbeveloper ~DefaultDeleter() 786396865dSbeveloper { 799def3bf7SStephan Aßmus if (BMediaRoster::sDefaultInstance) { 809def3bf7SStephan Aßmus BMediaRoster::sDefaultInstance->Lock(); 819def3bf7SStephan Aßmus BMediaRoster::sDefaultInstance->Quit(); 826396865dSbeveloper } 836396865dSbeveloper } 848b04ffc1Sbeveloper }; 8552a38012Sejakowatz 868b04ffc1Sbeveloper } } // BPrivate::media 878b04ffc1Sbeveloper using namespace BPrivate::media; 8852a38012Sejakowatz 898b04ffc1Sbeveloper // DefaultDeleter will delete the BMediaRoster object in it's destructor. 908b04ffc1Sbeveloper DefaultDeleter _deleter; 9152a38012Sejakowatz 9234c72144SAxel Dörfler BMediaRosterEx::BMediaRosterEx(status_t* _error) 93dcfb6bfcSJérôme Duval : BMediaRoster() 94dcfb6bfcSJérôme Duval { 95dcfb6bfcSJérôme Duval status_t rv; 96dcfb6bfcSJérôme Duval // register this application with the media server 97dcfb6bfcSJérôme Duval server_register_app_request request; 98dcfb6bfcSJérôme Duval server_register_app_reply reply; 99dcfb6bfcSJérôme Duval request.team = team; 100dcfb6bfcSJérôme Duval request.messenger = BMessenger(NULL, this); 10134c72144SAxel Dörfler rv = QueryServer(SERVER_REGISTER_APP, &request, sizeof(request), &reply, 10234c72144SAxel Dörfler sizeof(reply)); 103a7fb4c16SMaurice Kalinowski if (rv != B_OK) 10434c72144SAxel Dörfler *_error = B_MEDIA_SYSTEM_FAILURE; 105a7fb4c16SMaurice Kalinowski else 10634c72144SAxel Dörfler *_error = B_OK; 107dcfb6bfcSJérôme Duval } 108dcfb6bfcSJérôme Duval 10934c72144SAxel Dörfler 1103620737cSbeveloper status_t 11154187cc6Sbeveloper BMediaRosterEx::SaveNodeConfiguration(BMediaNode* node) 11254187cc6Sbeveloper { 11354187cc6Sbeveloper BMediaAddOn *addon; 11454187cc6Sbeveloper media_addon_id addonid; 11554187cc6Sbeveloper int32 flavorid; 11654187cc6Sbeveloper addon = node->AddOn(&flavorid); 11754187cc6Sbeveloper if (!addon) { 1188056f0dbSStephan Aßmus // NOTE: This node could have been created by an application, 1198056f0dbSStephan Aßmus // it does not mean there is an error. 12034c72144SAxel Dörfler // TODO: this check incorrectly triggers on BeOS R5 BT848 node 1218056f0dbSStephan Aßmus TRACE("BMediaRosterEx::SaveNodeConfiguration node %ld not instantiated " 1228056f0dbSStephan Aßmus "from BMediaAddOn!\n", node->ID()); 12354187cc6Sbeveloper return B_ERROR; 12454187cc6Sbeveloper } 12554187cc6Sbeveloper addonid = addon->AddonID(); 12654187cc6Sbeveloper 12734c72144SAxel Dörfler // TODO: fix this 1288056f0dbSStephan Aßmus printf("### BMediaRosterEx::SaveNodeConfiguration should save addon-id " 1298056f0dbSStephan Aßmus "%ld, flavor-id %ld config NOW!\n", addonid, flavorid); 13054187cc6Sbeveloper return B_OK; 13154187cc6Sbeveloper } 13254187cc6Sbeveloper 13334c72144SAxel Dörfler 13454187cc6Sbeveloper status_t 1358b940bb4SStephan Aßmus BMediaRosterEx::LoadNodeConfiguration(media_addon_id addonid, int32 flavorid, 1368b940bb4SStephan Aßmus BMessage *out_msg) 13754187cc6Sbeveloper { 13834c72144SAxel Dörfler // TODO: fix this 13954187cc6Sbeveloper out_msg->MakeEmpty(); // to be fully R5 compliant 1408b940bb4SStephan Aßmus printf("### BMediaRosterEx::LoadNodeConfiguration should load addon-id " 1418b940bb4SStephan Aßmus "%ld, flavor-id %ld config NOW!\n", addonid, flavorid); 14254187cc6Sbeveloper return B_OK; 14354187cc6Sbeveloper } 14454187cc6Sbeveloper 14534c72144SAxel Dörfler 14654187cc6Sbeveloper status_t 14734c72144SAxel Dörfler BMediaRosterEx::IncrementAddonFlavorInstancesCount(media_addon_id addonid, 14834c72144SAxel Dörfler int32 flavorid) 14954187cc6Sbeveloper { 15073794717Sbeveloper server_change_addon_flavor_instances_count_request request; 15173794717Sbeveloper server_change_addon_flavor_instances_count_reply reply; 15273794717Sbeveloper 15373794717Sbeveloper request.addonid = addonid; 15473794717Sbeveloper request.flavorid = flavorid; 15573794717Sbeveloper request.delta = 1; 15673794717Sbeveloper request.team = team; 15734c72144SAxel Dörfler return QueryServer(SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT, &request, 15834c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 15954187cc6Sbeveloper } 16054187cc6Sbeveloper 16134c72144SAxel Dörfler 16254187cc6Sbeveloper status_t 16334c72144SAxel Dörfler BMediaRosterEx::DecrementAddonFlavorInstancesCount(media_addon_id addonid, 16434c72144SAxel Dörfler int32 flavorid) 16554187cc6Sbeveloper { 16673794717Sbeveloper server_change_addon_flavor_instances_count_request request; 16773794717Sbeveloper server_change_addon_flavor_instances_count_reply reply; 16873794717Sbeveloper 16973794717Sbeveloper request.addonid = addonid; 17073794717Sbeveloper request.flavorid = flavorid; 17173794717Sbeveloper request.delta = -1; 17273794717Sbeveloper request.team = team; 17334c72144SAxel Dörfler return QueryServer(SERVER_CHANGE_ADDON_FLAVOR_INSTANCES_COUNT, &request, 17434c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 17554187cc6Sbeveloper } 17654187cc6Sbeveloper 17734c72144SAxel Dörfler 17854187cc6Sbeveloper status_t 17954187cc6Sbeveloper BMediaRosterEx::SetNodeCreator(media_node_id node, team_id creator) 18054187cc6Sbeveloper { 18154187cc6Sbeveloper server_set_node_creator_request request; 18254187cc6Sbeveloper server_set_node_creator_reply reply; 18354187cc6Sbeveloper 18454187cc6Sbeveloper request.node = node; 18554187cc6Sbeveloper request.creator = creator; 18634c72144SAxel Dörfler return QueryServer(SERVER_SET_NODE_CREATOR, &request, sizeof(request), 18734c72144SAxel Dörfler &reply, sizeof(reply)); 18854187cc6Sbeveloper } 18954187cc6Sbeveloper 19034c72144SAxel Dörfler 19154187cc6Sbeveloper status_t 19234c72144SAxel Dörfler BMediaRosterEx::GetNode(node_type type, media_node* out_node, 19334c72144SAxel Dörfler int32* out_input_id, BString* out_input_name) 19452a38012Sejakowatz { 19552a38012Sejakowatz if (out_node == NULL) 19652a38012Sejakowatz return B_BAD_VALUE; 19752a38012Sejakowatz 1988c6a6096Sbeveloper server_get_node_request request; 1998c6a6096Sbeveloper server_get_node_reply reply; 20052a38012Sejakowatz status_t rv; 20152a38012Sejakowatz 2028c6a6096Sbeveloper request.type = type; 2039e9417d2Sbeveloper request.team = team; 20434c72144SAxel Dörfler rv = QueryServer(SERVER_GET_NODE, &request, sizeof(request), &reply, 20534c72144SAxel Dörfler sizeof(reply)); 2068c6a6096Sbeveloper if (rv != B_OK) 2078c6a6096Sbeveloper return rv; 20852a38012Sejakowatz 20952a38012Sejakowatz *out_node = reply.node; 21052a38012Sejakowatz if (out_input_id) 21152a38012Sejakowatz *out_input_id = reply.input_id; 21252a38012Sejakowatz if (out_input_name) 21352a38012Sejakowatz *out_input_name = reply.input_name; 2148c6a6096Sbeveloper return rv; 21552a38012Sejakowatz } 21652a38012Sejakowatz 21734c72144SAxel Dörfler 2183620737cSbeveloper status_t 21934c72144SAxel Dörfler BMediaRosterEx::SetNode(node_type type, const media_node* node, 22034c72144SAxel Dörfler const dormant_node_info* info, const media_input* input) 22152a38012Sejakowatz { 2228c6a6096Sbeveloper server_set_node_request request; 2238c6a6096Sbeveloper server_set_node_reply reply; 22452a38012Sejakowatz 2258c6a6096Sbeveloper request.type = type; 22634c72144SAxel Dörfler request.use_node = node != NULL; 22734c72144SAxel Dörfler if (node != NULL) 2288c6a6096Sbeveloper request.node = *node; 22934c72144SAxel Dörfler request.use_dni = info != NULL; 23034c72144SAxel Dörfler if (info != NULL) 2318c6a6096Sbeveloper request.dni = *info; 23234c72144SAxel Dörfler request.use_input = input != NULL; 23334c72144SAxel Dörfler if (input != NULL) 2348c6a6096Sbeveloper request.input = *input; 23552a38012Sejakowatz 23634c72144SAxel Dörfler return QueryServer(SERVER_SET_NODE, &request, sizeof(request), &reply, 23734c72144SAxel Dörfler sizeof(reply)); 23852a38012Sejakowatz } 23952a38012Sejakowatz 24034c72144SAxel Dörfler 2413620737cSbeveloper status_t 2428b04ffc1Sbeveloper BMediaRosterEx::GetAllOutputs(const media_node& node, List<media_output>* list) 2433620737cSbeveloper { 2443620737cSbeveloper int32 cookie; 2453620737cSbeveloper status_t rv; 2463620737cSbeveloper status_t result; 2473620737cSbeveloper 24834c72144SAxel Dörfler PRINT(4, "BMediaRosterEx::GetAllOutputs() node %ld, port %ld\n", node.node, 24934c72144SAxel Dörfler node.port); 2505ac4fbd7Sbeveloper 25165b73ae4SMarcus Overhagen if (!(node.kind & B_BUFFER_PRODUCER)) { 25234c72144SAxel Dörfler ERROR("BMediaRosterEx::GetAllOutputs: node %ld is not a " 25334c72144SAxel Dörfler "B_BUFFER_PRODUCER\n", node.node); 25465b73ae4SMarcus Overhagen return B_MEDIA_BAD_NODE; 25565b73ae4SMarcus Overhagen } 25665b73ae4SMarcus Overhagen 2573620737cSbeveloper result = B_OK; 2583620737cSbeveloper cookie = 0; 25976669a29Sbeveloper list->MakeEmpty(); 2603620737cSbeveloper for (;;) { 2613620737cSbeveloper producer_get_next_output_request request; 2623620737cSbeveloper producer_get_next_output_reply reply; 2633620737cSbeveloper request.cookie = cookie; 26434c72144SAxel Dörfler rv = QueryPort(node.port, PRODUCER_GET_NEXT_OUTPUT, &request, 26534c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 2663620737cSbeveloper if (rv != B_OK) 2673620737cSbeveloper break; 2683620737cSbeveloper cookie = reply.cookie; 26976669a29Sbeveloper if (!list->Insert(reply.output)) { 2705ac4fbd7Sbeveloper ERROR("GetAllOutputs: list->Insert failed\n"); 2713620737cSbeveloper result = B_ERROR; 2723620737cSbeveloper } 2735ac4fbd7Sbeveloper #if DEBUG >= 3 2745ac4fbd7Sbeveloper PRINT(3," next cookie %ld, ", cookie); 2755ac4fbd7Sbeveloper PRINT_OUTPUT("output ", reply.output); 2765ac4fbd7Sbeveloper #endif 2773620737cSbeveloper } 2783620737cSbeveloper 2793620737cSbeveloper producer_dispose_output_cookie_request request; 2803620737cSbeveloper producer_dispose_output_cookie_reply reply; 28134c72144SAxel Dörfler QueryPort(node.port, PRODUCER_DISPOSE_OUTPUT_COOKIE, &request, 28234c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 2833620737cSbeveloper 2843620737cSbeveloper return result; 2853620737cSbeveloper } 2863620737cSbeveloper 28734c72144SAxel Dörfler 2883620737cSbeveloper status_t 2894d2d96e0Sbeveloper BMediaRosterEx::GetAllOutputs(BBufferProducer* node, List<media_output>* list) 2904d2d96e0Sbeveloper { 2914d2d96e0Sbeveloper int32 cookie; 2924d2d96e0Sbeveloper status_t result; 2934d2d96e0Sbeveloper 2944d2d96e0Sbeveloper PRINT(4, "BMediaRosterEx::GetAllOutputs() (by pointer) node %ld, port %ld\n", node->ID(), node->ControlPort()); 2954d2d96e0Sbeveloper 2964d2d96e0Sbeveloper result = B_OK; 2974d2d96e0Sbeveloper cookie = 0; 2984d2d96e0Sbeveloper list->MakeEmpty(); 2994d2d96e0Sbeveloper for (;;) { 3004d2d96e0Sbeveloper media_output output; 3014d2d96e0Sbeveloper if (B_OK != node->GetNextOutput(&cookie, &output)) 3024d2d96e0Sbeveloper break; 3034d2d96e0Sbeveloper if (!list->Insert(output)) { 3044d2d96e0Sbeveloper ERROR("GetAllOutputs: list->Insert failed\n"); 3054d2d96e0Sbeveloper result = B_ERROR; 3064d2d96e0Sbeveloper } 3074d2d96e0Sbeveloper #if DEBUG >= 3 3084d2d96e0Sbeveloper PRINT(3," next cookie %ld, ", cookie); 3094d2d96e0Sbeveloper PRINT_OUTPUT("output ", output); 3104d2d96e0Sbeveloper #endif 3114d2d96e0Sbeveloper } 3124d2d96e0Sbeveloper node->DisposeOutputCookie(cookie); 3134d2d96e0Sbeveloper return result; 3144d2d96e0Sbeveloper } 3154d2d96e0Sbeveloper 31634c72144SAxel Dörfler 3174d2d96e0Sbeveloper status_t 3188b04ffc1Sbeveloper BMediaRosterEx::GetAllInputs(const media_node& node, List<media_input>* list) 3193620737cSbeveloper { 3203620737cSbeveloper int32 cookie; 3213620737cSbeveloper status_t rv; 3223620737cSbeveloper status_t result; 3233620737cSbeveloper 32434c72144SAxel Dörfler PRINT(4, "BMediaRosterEx::GetAllInputs() node %ld, port %ld\n", node.node, 32534c72144SAxel Dörfler node.port); 3265ac4fbd7Sbeveloper 32765b73ae4SMarcus Overhagen if (!(node.kind & B_BUFFER_CONSUMER)) { 32834c72144SAxel Dörfler ERROR("BMediaRosterEx::GetAllInputs: node %ld is not a " 32934c72144SAxel Dörfler "B_BUFFER_CONSUMER\n", node.node); 33065b73ae4SMarcus Overhagen return B_MEDIA_BAD_NODE; 33165b73ae4SMarcus Overhagen } 33265b73ae4SMarcus Overhagen 3333620737cSbeveloper result = B_OK; 3343620737cSbeveloper cookie = 0; 33576669a29Sbeveloper list->MakeEmpty(); 3363620737cSbeveloper for (;;) { 3373620737cSbeveloper consumer_get_next_input_request request; 3383620737cSbeveloper consumer_get_next_input_reply reply; 3393620737cSbeveloper request.cookie = cookie; 34034c72144SAxel Dörfler rv = QueryPort(node.port, CONSUMER_GET_NEXT_INPUT, &request, 34134c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 3423620737cSbeveloper if (rv != B_OK) 3433620737cSbeveloper break; 3443620737cSbeveloper cookie = reply.cookie; 34576669a29Sbeveloper if (!list->Insert(reply.input)) { 3465ac4fbd7Sbeveloper ERROR("GetAllInputs: list->Insert failed\n"); 3473620737cSbeveloper result = B_ERROR; 3483620737cSbeveloper } 3495ac4fbd7Sbeveloper #if DEBUG >= 3 3505ac4fbd7Sbeveloper PRINT(3," next cookie %ld, ", cookie); 3515ac4fbd7Sbeveloper PRINT_OUTPUT("input ", reply.input); 3525ac4fbd7Sbeveloper #endif 3533620737cSbeveloper } 3543620737cSbeveloper 3553620737cSbeveloper consumer_dispose_input_cookie_request request; 3563620737cSbeveloper consumer_dispose_input_cookie_reply reply; 35734c72144SAxel Dörfler QueryPort(node.port, CONSUMER_DISPOSE_INPUT_COOKIE, &request, 35834c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 3593620737cSbeveloper 3603620737cSbeveloper return result; 3613620737cSbeveloper } 3623620737cSbeveloper 36334c72144SAxel Dörfler 3643620737cSbeveloper status_t 3654d2d96e0Sbeveloper BMediaRosterEx::GetAllInputs(BBufferConsumer* node, List<media_input>* list) 3664d2d96e0Sbeveloper { 3674d2d96e0Sbeveloper int32 cookie; 3684d2d96e0Sbeveloper status_t result; 3694d2d96e0Sbeveloper 3704d2d96e0Sbeveloper PRINT(4, "BMediaRosterEx::GetAllInputs() (by pointer) node %ld, port %ld\n", node->ID(), node->ControlPort()); 3714d2d96e0Sbeveloper 3724d2d96e0Sbeveloper result = B_OK; 3734d2d96e0Sbeveloper cookie = 0; 3744d2d96e0Sbeveloper list->MakeEmpty(); 3754d2d96e0Sbeveloper for (;;) { 3764d2d96e0Sbeveloper media_input input; 3774d2d96e0Sbeveloper if (B_OK != node->GetNextInput(&cookie, &input)) 3784d2d96e0Sbeveloper break; 3794d2d96e0Sbeveloper if (!list->Insert(input)) { 3804d2d96e0Sbeveloper ERROR("GetAllInputs: list->Insert failed\n"); 3814d2d96e0Sbeveloper result = B_ERROR; 3824d2d96e0Sbeveloper } 3834d2d96e0Sbeveloper #if DEBUG >= 3 3844d2d96e0Sbeveloper PRINT(3," next cookie %ld, ", cookie); 3854d2d96e0Sbeveloper PRINT_INPUT("input ", input); 3864d2d96e0Sbeveloper #endif 3874d2d96e0Sbeveloper } 3884d2d96e0Sbeveloper node->DisposeInputCookie(cookie); 3894d2d96e0Sbeveloper return result; 3904d2d96e0Sbeveloper } 3914d2d96e0Sbeveloper 39234c72144SAxel Dörfler 3934d2d96e0Sbeveloper status_t 3948b04ffc1Sbeveloper BMediaRosterEx::PublishOutputs(const media_node& node, List<media_output>* list) 3953620737cSbeveloper { 3963620737cSbeveloper server_publish_outputs_request request; 3973620737cSbeveloper server_publish_outputs_reply reply; 3983620737cSbeveloper media_output* output; 3993620737cSbeveloper media_output* outputs; 4003620737cSbeveloper int32 count; 401a7b41a96Sbeveloper status_t rv; 4023620737cSbeveloper 40376669a29Sbeveloper count = list->CountItems(); 4043620737cSbeveloper TRACE("PublishOutputs: publishing %ld\n", count); 4053620737cSbeveloper 4063620737cSbeveloper request.node = node; 4073620737cSbeveloper request.count = count; 4083620737cSbeveloper if (count > MAX_OUTPUTS) { 4093620737cSbeveloper void *start_addr; 4103620737cSbeveloper size_t size; 41140f36b03Sbeveloper size = ROUND_UP_TO_PAGE(count * sizeof(media_output)); 41234c72144SAxel Dörfler request.area = create_area("publish outputs", &start_addr, 41334c72144SAxel Dörfler B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); 4143620737cSbeveloper if (request.area < B_OK) { 41534c72144SAxel Dörfler ERROR("PublishOutputs: failed to create area, %#lx\n", 41634c72144SAxel Dörfler request.area); 4173620737cSbeveloper return (status_t)request.area; 4183620737cSbeveloper } 4193620737cSbeveloper outputs = static_cast<media_output *>(start_addr); 4203620737cSbeveloper } else { 4213620737cSbeveloper request.area = -1; 4223620737cSbeveloper outputs = request.outputs; 4233620737cSbeveloper } 42476669a29Sbeveloper TRACE("PublishOutputs: area %ld\n", request.area); 4253620737cSbeveloper 42676669a29Sbeveloper int i; 42776669a29Sbeveloper for (i = 0, list->Rewind(); list->GetNext(&output); i++) { 42876669a29Sbeveloper ASSERT(i < count); 4293620737cSbeveloper outputs[i] = *output; 4303620737cSbeveloper } 4313620737cSbeveloper 43234c72144SAxel Dörfler rv = QueryServer(SERVER_PUBLISH_OUTPUTS, &request, sizeof(request), 43334c72144SAxel Dörfler &reply, sizeof(reply)); 434a7b41a96Sbeveloper 435a7b41a96Sbeveloper if (request.area != -1) 436a7b41a96Sbeveloper delete_area(request.area); 437a7b41a96Sbeveloper 438a7b41a96Sbeveloper return rv; 4393620737cSbeveloper } 4403620737cSbeveloper 44134c72144SAxel Dörfler 4423620737cSbeveloper status_t 4438b04ffc1Sbeveloper BMediaRosterEx::PublishInputs(const media_node& node, List<media_input>* list) 4443620737cSbeveloper { 4453620737cSbeveloper server_publish_inputs_request request; 4463620737cSbeveloper server_publish_inputs_reply reply; 4473620737cSbeveloper media_input* input; 4483620737cSbeveloper media_input* inputs; 4493620737cSbeveloper int32 count; 450a7b41a96Sbeveloper status_t rv; 4513620737cSbeveloper 45276669a29Sbeveloper count = list->CountItems(); 4533620737cSbeveloper TRACE("PublishInputs: publishing %ld\n", count); 4543620737cSbeveloper 4553620737cSbeveloper request.node = node; 4563620737cSbeveloper request.count = count; 4573620737cSbeveloper if (count > MAX_INPUTS) { 4583620737cSbeveloper void* start_addr; 4593620737cSbeveloper size_t size; 46040f36b03Sbeveloper size = ROUND_UP_TO_PAGE(count * sizeof(media_input)); 46134c72144SAxel Dörfler request.area = create_area("publish inputs", &start_addr, 46234c72144SAxel Dörfler B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); 4633620737cSbeveloper if (request.area < B_OK) { 4645ac4fbd7Sbeveloper ERROR("PublishInputs: failed to create area, %#lx\n", request.area); 4653620737cSbeveloper return (status_t)request.area; 4663620737cSbeveloper } 4673620737cSbeveloper inputs = static_cast<media_input *>(start_addr); 4683620737cSbeveloper } else { 4693620737cSbeveloper request.area = -1; 4703620737cSbeveloper inputs = request.inputs; 4713620737cSbeveloper } 47276669a29Sbeveloper TRACE("PublishInputs: area %ld\n", request.area); 4733620737cSbeveloper 47476669a29Sbeveloper int i; 47576669a29Sbeveloper for (i = 0, list->Rewind(); list->GetNext(&input); i++) { 47676669a29Sbeveloper ASSERT(i < count); 4773620737cSbeveloper inputs[i] = *input; 4783620737cSbeveloper } 4793620737cSbeveloper 48034c72144SAxel Dörfler rv = QueryServer(SERVER_PUBLISH_INPUTS, &request, sizeof(request), 48134c72144SAxel Dörfler &reply, sizeof(reply)); 482a7b41a96Sbeveloper 483a7b41a96Sbeveloper if (request.area != -1) 484a7b41a96Sbeveloper delete_area(request.area); 485a7b41a96Sbeveloper 486a7b41a96Sbeveloper return rv; 4873620737cSbeveloper } 4883620737cSbeveloper 48934c72144SAxel Dörfler 49034c72144SAxel Dörfler BTimeSource* 49134c72144SAxel Dörfler BMediaRosterEx::MakeTimeSourceObject(media_node_id timesourceID) 49234c72144SAxel Dörfler { 49334c72144SAxel Dörfler BTimeSource* source; 49434c72144SAxel Dörfler media_node clone; 49534c72144SAxel Dörfler status_t rv; 49634c72144SAxel Dörfler 49734c72144SAxel Dörfler rv = GetNodeFor(timesourceID, &clone); 49834c72144SAxel Dörfler if (rv != B_OK) { 49934c72144SAxel Dörfler ERROR("BMediaRosterEx::MakeTimeSourceObject: GetNodeFor failed\n"); 50034c72144SAxel Dörfler return NULL; 50134c72144SAxel Dörfler } 50234c72144SAxel Dörfler 50334c72144SAxel Dörfler source = _TimeSourceObjectManager->GetTimeSource(clone); 50434c72144SAxel Dörfler if (source == NULL) { 50534c72144SAxel Dörfler ERROR("BMediaRosterEx::MakeTimeSourceObject: GetTimeSource failed\n"); 50634c72144SAxel Dörfler return NULL; 50734c72144SAxel Dörfler } 50834c72144SAxel Dörfler 50934c72144SAxel Dörfler // TODO: release? 51034c72144SAxel Dörfler ReleaseNode(clone); 51134c72144SAxel Dörfler 51234c72144SAxel Dörfler return source; 51334c72144SAxel Dörfler } 51434c72144SAxel Dörfler 51534c72144SAxel Dörfler 51634c72144SAxel Dörfler // #pragma mark - public BMediaRoster 51734c72144SAxel Dörfler 51852a38012Sejakowatz 51952a38012Sejakowatz status_t 52034c72144SAxel Dörfler BMediaRoster::GetVideoInput(media_node* _node) 52152a38012Sejakowatz { 52252a38012Sejakowatz CALLED(); 52334c72144SAxel Dörfler return MediaRosterEx(this)->GetNode(VIDEO_INPUT, _node); 52452a38012Sejakowatz } 52552a38012Sejakowatz 52652a38012Sejakowatz 52752a38012Sejakowatz status_t 52834c72144SAxel Dörfler BMediaRoster::GetAudioInput(media_node* _node) 52952a38012Sejakowatz { 53052a38012Sejakowatz CALLED(); 53134c72144SAxel Dörfler return MediaRosterEx(this)->GetNode(AUDIO_INPUT, _node); 53252a38012Sejakowatz } 53352a38012Sejakowatz 53452a38012Sejakowatz 53552a38012Sejakowatz status_t 53634c72144SAxel Dörfler BMediaRoster::GetVideoOutput(media_node* _node) 53752a38012Sejakowatz { 53852a38012Sejakowatz CALLED(); 53934c72144SAxel Dörfler return MediaRosterEx(this)->GetNode(VIDEO_OUTPUT, _node); 54052a38012Sejakowatz } 54152a38012Sejakowatz 54252a38012Sejakowatz 54352a38012Sejakowatz status_t 54434c72144SAxel Dörfler BMediaRoster::GetAudioMixer(media_node* _node) 54552a38012Sejakowatz { 54652a38012Sejakowatz CALLED(); 54734c72144SAxel Dörfler return MediaRosterEx(this)->GetNode(AUDIO_MIXER, _node); 54852a38012Sejakowatz } 54952a38012Sejakowatz 55052a38012Sejakowatz 55152a38012Sejakowatz status_t 55234c72144SAxel Dörfler BMediaRoster::GetAudioOutput(media_node* _node) 55352a38012Sejakowatz { 55452a38012Sejakowatz CALLED(); 55534c72144SAxel Dörfler return MediaRosterEx(this)->GetNode(AUDIO_OUTPUT, _node); 55652a38012Sejakowatz } 55752a38012Sejakowatz 55852a38012Sejakowatz 55952a38012Sejakowatz status_t 56034c72144SAxel Dörfler BMediaRoster::GetAudioOutput(media_node* _node, int32* _inputID, 56134c72144SAxel Dörfler BString* _inputName) 56252a38012Sejakowatz { 56352a38012Sejakowatz CALLED(); 56434c72144SAxel Dörfler return MediaRosterEx(this)->GetNode(AUDIO_OUTPUT_EX, _node, _inputID, 56534c72144SAxel Dörfler _inputName); 56652a38012Sejakowatz } 56752a38012Sejakowatz 56852a38012Sejakowatz 56952a38012Sejakowatz status_t 57034c72144SAxel Dörfler BMediaRoster::GetTimeSource(media_node* _node) 57152a38012Sejakowatz { 57252a38012Sejakowatz CALLED(); 57386bce45bSbeveloper status_t rv; 57486bce45bSbeveloper 57534c72144SAxel Dörfler // TODO: need to do this in a nicer way. 57686bce45bSbeveloper 57734c72144SAxel Dörfler rv = MediaRosterEx(this)->GetNode(TIME_SOURCE, _node); 57886bce45bSbeveloper if (rv != B_OK) 57986bce45bSbeveloper return rv; 58086bce45bSbeveloper 58186bce45bSbeveloper // We don't do reference counting for timesources, that's why we 58286bce45bSbeveloper // release the node immediately. 58334c72144SAxel Dörfler ReleaseNode(*_node); 58486bce45bSbeveloper 58586bce45bSbeveloper // we need to remember to not use this node with server side reference counting 58634c72144SAxel Dörfler _node->kind |= NODE_KIND_NO_REFCOUNTING; 58786bce45bSbeveloper return B_OK; 58852a38012Sejakowatz } 58952a38012Sejakowatz 59052a38012Sejakowatz 59152a38012Sejakowatz status_t 59252a38012Sejakowatz BMediaRoster::SetVideoInput(const media_node& producer) 59352a38012Sejakowatz { 59452a38012Sejakowatz CALLED(); 5958b04ffc1Sbeveloper return MediaRosterEx(this)->SetNode(VIDEO_INPUT, &producer); 59652a38012Sejakowatz } 59752a38012Sejakowatz 59852a38012Sejakowatz 59952a38012Sejakowatz status_t 60052a38012Sejakowatz BMediaRoster::SetVideoInput(const dormant_node_info& producer) 60152a38012Sejakowatz { 60252a38012Sejakowatz CALLED(); 6038b04ffc1Sbeveloper return MediaRosterEx(this)->SetNode(VIDEO_INPUT, NULL, &producer); 60452a38012Sejakowatz } 60552a38012Sejakowatz 60652a38012Sejakowatz 60752a38012Sejakowatz status_t 60852a38012Sejakowatz BMediaRoster::SetAudioInput(const media_node& producer) 60952a38012Sejakowatz { 61052a38012Sejakowatz CALLED(); 6118b04ffc1Sbeveloper return MediaRosterEx(this)->SetNode(AUDIO_INPUT, &producer); 61252a38012Sejakowatz } 61352a38012Sejakowatz 61452a38012Sejakowatz 61552a38012Sejakowatz status_t 61652a38012Sejakowatz BMediaRoster::SetAudioInput(const dormant_node_info& producer) 61752a38012Sejakowatz { 61852a38012Sejakowatz CALLED(); 6198b04ffc1Sbeveloper return MediaRosterEx(this)->SetNode(AUDIO_INPUT, NULL, &producer); 62052a38012Sejakowatz } 62152a38012Sejakowatz 62252a38012Sejakowatz 62352a38012Sejakowatz status_t 62452a38012Sejakowatz BMediaRoster::SetVideoOutput(const media_node& consumer) 62552a38012Sejakowatz { 62652a38012Sejakowatz CALLED(); 6278b04ffc1Sbeveloper return MediaRosterEx(this)->SetNode(VIDEO_OUTPUT, &consumer); 62852a38012Sejakowatz } 62952a38012Sejakowatz 63052a38012Sejakowatz 63152a38012Sejakowatz status_t 63252a38012Sejakowatz BMediaRoster::SetVideoOutput(const dormant_node_info& consumer) 63352a38012Sejakowatz { 63452a38012Sejakowatz CALLED(); 6358b04ffc1Sbeveloper return MediaRosterEx(this)->SetNode(VIDEO_OUTPUT, NULL, &consumer); 63652a38012Sejakowatz } 63752a38012Sejakowatz 63852a38012Sejakowatz 63952a38012Sejakowatz status_t 64052a38012Sejakowatz BMediaRoster::SetAudioOutput(const media_node& consumer) 64152a38012Sejakowatz { 64252a38012Sejakowatz CALLED(); 6438b04ffc1Sbeveloper return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, &consumer); 64452a38012Sejakowatz } 64552a38012Sejakowatz 64652a38012Sejakowatz 64752a38012Sejakowatz status_t 64834c72144SAxel Dörfler BMediaRoster::SetAudioOutput(const media_input& input) 64952a38012Sejakowatz { 65052a38012Sejakowatz CALLED(); 65134c72144SAxel Dörfler return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, NULL, NULL, &input); 65252a38012Sejakowatz } 65352a38012Sejakowatz 65452a38012Sejakowatz 65552a38012Sejakowatz status_t 65652a38012Sejakowatz BMediaRoster::SetAudioOutput(const dormant_node_info& consumer) 65752a38012Sejakowatz { 65852a38012Sejakowatz CALLED(); 6598b04ffc1Sbeveloper return MediaRosterEx(this)->SetNode(AUDIO_OUTPUT, NULL, &consumer); 66052a38012Sejakowatz } 66152a38012Sejakowatz 66252a38012Sejakowatz 66352a38012Sejakowatz status_t 66434c72144SAxel Dörfler BMediaRoster::GetNodeFor(media_node_id node, media_node* clone) 66552a38012Sejakowatz { 6669e9417d2Sbeveloper CALLED(); 6679e9417d2Sbeveloper if (clone == NULL) 6689e9417d2Sbeveloper return B_BAD_VALUE; 66965b73ae4SMarcus Overhagen if (IS_INVALID_NODEID(node)) 6709e9417d2Sbeveloper return B_MEDIA_BAD_NODE; 6719e9417d2Sbeveloper 6729e9417d2Sbeveloper server_get_node_for_request request; 6739e9417d2Sbeveloper server_get_node_for_reply reply; 6749e9417d2Sbeveloper status_t rv; 6759e9417d2Sbeveloper 6769e9417d2Sbeveloper request.nodeid = node; 6779e9417d2Sbeveloper request.team = team; 6789e9417d2Sbeveloper 67934c72144SAxel Dörfler rv = QueryServer(SERVER_GET_NODE_FOR, &request, sizeof(request), &reply, 68034c72144SAxel Dörfler sizeof(reply)); 6819e9417d2Sbeveloper if (rv != B_OK) 6829e9417d2Sbeveloper return rv; 6839e9417d2Sbeveloper 6849e9417d2Sbeveloper *clone = reply.clone; 6859e9417d2Sbeveloper return B_OK; 68652a38012Sejakowatz } 68752a38012Sejakowatz 68852a38012Sejakowatz 68952a38012Sejakowatz status_t 69052a38012Sejakowatz BMediaRoster::GetSystemTimeSource(media_node* clone) 69152a38012Sejakowatz { 69252a38012Sejakowatz CALLED(); 69386bce45bSbeveloper status_t rv; 69486bce45bSbeveloper 69534c72144SAxel Dörfler // TODO: need to do this in a nicer way. 69686bce45bSbeveloper 69786bce45bSbeveloper rv = MediaRosterEx(this)->GetNode(SYSTEM_TIME_SOURCE, clone); 69886bce45bSbeveloper if (rv != B_OK) 69986bce45bSbeveloper return rv; 70086bce45bSbeveloper 70186bce45bSbeveloper // We don't do reference counting for timesources, that's why we 70286bce45bSbeveloper // release the node immediately. 70386bce45bSbeveloper ReleaseNode(*clone); 70486bce45bSbeveloper 70534c72144SAxel Dörfler // we need to remember to not use this node with server side reference 70634c72144SAxel Dörfler // counting 70786bce45bSbeveloper clone->kind |= NODE_KIND_NO_REFCOUNTING; 70886bce45bSbeveloper 70986bce45bSbeveloper return B_OK; 71052a38012Sejakowatz } 71152a38012Sejakowatz 71252a38012Sejakowatz 71352a38012Sejakowatz status_t 71452a38012Sejakowatz BMediaRoster::ReleaseNode(const media_node& node) 71552a38012Sejakowatz { 7169e9417d2Sbeveloper CALLED(); 71740f36b03Sbeveloper if (IS_INVALID_NODE(node)) 7189e9417d2Sbeveloper return B_MEDIA_BAD_NODE; 71952a38012Sejakowatz 72086bce45bSbeveloper if (node.kind & NODE_KIND_NO_REFCOUNTING) { 72134c72144SAxel Dörfler printf("BMediaRoster::ReleaseNode, trying to release reference " 72234c72144SAxel Dörfler "counting disabled timesource, node %ld, port %ld, team %ld\n", 72334c72144SAxel Dörfler node.node, node.port, team); 72486bce45bSbeveloper return B_OK; 72586bce45bSbeveloper } 72686bce45bSbeveloper 7279e9417d2Sbeveloper server_release_node_request request; 7289e9417d2Sbeveloper server_release_node_reply reply; 729cf4e2277Sbeveloper status_t rv; 7309e9417d2Sbeveloper 7319e9417d2Sbeveloper request.node = node; 7329e9417d2Sbeveloper request.team = team; 7339e9417d2Sbeveloper 73434c72144SAxel Dörfler TRACE("BMediaRoster::ReleaseNode, node %ld, port %ld, team %ld\n", 73534c72144SAxel Dörfler node.node, node.port, team); 736cf4e2277Sbeveloper 73734c72144SAxel Dörfler rv = QueryServer(SERVER_RELEASE_NODE, &request, sizeof(request), &reply, 73834c72144SAxel Dörfler sizeof(reply)); 739cf4e2277Sbeveloper if (rv != B_OK) { 74034c72144SAxel Dörfler ERROR("BMediaRoster::ReleaseNode FAILED, node %ld, port %ld, team " 74134c72144SAxel Dörfler "%ld!\n", node.node, node.port, team); 742cf4e2277Sbeveloper } 743cf4e2277Sbeveloper return rv; 7449e9417d2Sbeveloper } 74552a38012Sejakowatz 74634c72144SAxel Dörfler 74752a38012Sejakowatz BTimeSource* 74834c72144SAxel Dörfler BMediaRoster::MakeTimeSourceFor(const media_node& forNode) 74952a38012Sejakowatz { 750f180ef79Sbeveloper // MakeTimeSourceFor() returns a BTimeSource object 751f180ef79Sbeveloper // corresponding to the specified node's time source. 752f180ef79Sbeveloper 753835140c8Sbeveloper CALLED(); 754f180ef79Sbeveloper 75534c72144SAxel Dörfler if (IS_SYSTEM_TIMESOURCE(forNode)) { 756f180ef79Sbeveloper // special handling for the system time source 75734c72144SAxel Dörfler TRACE("BMediaRoster::MakeTimeSourceFor, asked for system time " 75834c72144SAxel Dörfler "source\n"); 75934c72144SAxel Dörfler return MediaRosterEx(this)->MakeTimeSourceObject( 76034c72144SAxel Dörfler NODE_SYSTEM_TIMESOURCE_ID); 761f180ef79Sbeveloper } 762f180ef79Sbeveloper 76334c72144SAxel Dörfler if (IS_INVALID_NODE(forNode)) { 76434c72144SAxel Dörfler ERROR("BMediaRoster::MakeTimeSourceFor: for_node invalid, node %ld, " 76534c72144SAxel Dörfler "port %ld, kinds 0x%lx\n", forNode.node, forNode.port, 76634c72144SAxel Dörfler forNode.kind); 7675917dd5bSbeveloper return NULL; 7680e21b167Sbeveloper } 7690e21b167Sbeveloper 77034c72144SAxel Dörfler TRACE("BMediaRoster::MakeTimeSourceFor: node %ld enter\n", forNode.node); 7715917dd5bSbeveloper 7725917dd5bSbeveloper node_get_timesource_request request; 7735917dd5bSbeveloper node_get_timesource_reply reply; 7745917dd5bSbeveloper BTimeSource *source; 7755917dd5bSbeveloper status_t rv; 7765917dd5bSbeveloper 77792e575c1Sbeveloper // ask the node to get it's current timesource id 77834c72144SAxel Dörfler rv = QueryPort(forNode.port, NODE_GET_TIMESOURCE, &request, 77934c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 7805917dd5bSbeveloper if (rv != B_OK) { 7815ac4fbd7Sbeveloper ERROR("BMediaRoster::MakeTimeSourceFor: request failed\n"); 7825917dd5bSbeveloper return NULL; 7835917dd5bSbeveloper } 7845917dd5bSbeveloper 7855917dd5bSbeveloper source = MediaRosterEx(this)->MakeTimeSourceObject(reply.timesource_id); 7865917dd5bSbeveloper 78734c72144SAxel Dörfler TRACE("BMediaRoster::MakeTimeSourceFor: node %ld leave\n", forNode.node); 788287f7492Sbeveloper 789835140c8Sbeveloper return source; 79052a38012Sejakowatz } 79152a38012Sejakowatz 79252a38012Sejakowatz 79352a38012Sejakowatz status_t 79434c72144SAxel Dörfler BMediaRoster::Connect(const media_source& from, const media_destination& to, 79534c72144SAxel Dörfler media_format* _format, media_output* _output, media_input* _input) 79652a38012Sejakowatz { 79734c72144SAxel Dörfler return BMediaRoster::Connect(from, to, _format, _output, _input, 0); 798eae26d3dSbeveloper } 799eae26d3dSbeveloper 800eae26d3dSbeveloper 801eae26d3dSbeveloper status_t 80234c72144SAxel Dörfler BMediaRoster::Connect(const media_source& from, const media_destination& to, 80334c72144SAxel Dörfler media_format* io_format, media_output* out_output, media_input* out_input, 80434c72144SAxel Dörfler uint32 in_flags, void* _reserved) 805eae26d3dSbeveloper { 80652a38012Sejakowatz CALLED(); 80752a38012Sejakowatz if (io_format == NULL || out_output == NULL || out_input == NULL) 80852a38012Sejakowatz return B_BAD_VALUE; 80940f36b03Sbeveloper if (IS_INVALID_SOURCE(from)) { 8105ac4fbd7Sbeveloper ERROR("BMediaRoster::Connect: media_source invalid\n"); 81152a38012Sejakowatz return B_MEDIA_BAD_SOURCE; 8129e9417d2Sbeveloper } 81340f36b03Sbeveloper if (IS_INVALID_DESTINATION(to)) { 8145ac4fbd7Sbeveloper ERROR("BMediaRoster::Connect: media_destination invalid\n"); 81552a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 8169e9417d2Sbeveloper } 81752a38012Sejakowatz 81852a38012Sejakowatz status_t rv; 81965b73ae4SMarcus Overhagen 82065b73ae4SMarcus Overhagen // find the output and input nodes 82134c72144SAxel Dörfler // TODO: isn't there a easier way? 82265b73ae4SMarcus Overhagen media_node sourcenode; 82365b73ae4SMarcus Overhagen media_node destnode; 82465b73ae4SMarcus Overhagen rv = GetNodeFor(NodeIDFor(from.port), &sourcenode); 82565b73ae4SMarcus Overhagen if (rv != B_OK) { 82634c72144SAxel Dörfler ERROR("BMediaRoster::Connect: Can't find source node for port %ld\n", 82734c72144SAxel Dörfler from.port); 82865b73ae4SMarcus Overhagen return B_MEDIA_BAD_SOURCE; 82965b73ae4SMarcus Overhagen } 83065b73ae4SMarcus Overhagen ReleaseNode(sourcenode); 83165b73ae4SMarcus Overhagen rv = GetNodeFor(NodeIDFor(to.port), &destnode); 83265b73ae4SMarcus Overhagen if (rv != B_OK) { 83334c72144SAxel Dörfler ERROR("BMediaRoster::Connect: Can't find destination node for port " 83434c72144SAxel Dörfler "%ld\n", to.port); 83565b73ae4SMarcus Overhagen return B_MEDIA_BAD_DESTINATION; 83665b73ae4SMarcus Overhagen } 83765b73ae4SMarcus Overhagen ReleaseNode(destnode); 83865b73ae4SMarcus Overhagen 83965b73ae4SMarcus Overhagen if (!(sourcenode.kind & B_BUFFER_PRODUCER)) { 84034c72144SAxel Dörfler ERROR("BMediaRoster::Connect: source node %ld is not a " 84134c72144SAxel Dörfler "B_BUFFER_PRODUCER\n", sourcenode.node); 84265b73ae4SMarcus Overhagen return B_MEDIA_BAD_SOURCE; 84365b73ae4SMarcus Overhagen } 84465b73ae4SMarcus Overhagen if (!(destnode.kind & B_BUFFER_CONSUMER)) { 84534c72144SAxel Dörfler ERROR("BMediaRoster::Connect: destination node %ld is not a " 84634c72144SAxel Dörfler "B_BUFFER_CONSUMER\n", destnode.node); 84765b73ae4SMarcus Overhagen return B_MEDIA_BAD_DESTINATION; 84865b73ae4SMarcus Overhagen } 84965b73ae4SMarcus Overhagen 8508c6a6096Sbeveloper producer_format_proposal_request request1; 8518c6a6096Sbeveloper producer_format_proposal_reply reply1; 85252a38012Sejakowatz 85334c72144SAxel Dörfler PRINT_FORMAT("BMediaRoster::Connect calling " 85434c72144SAxel Dörfler "BBufferProducer::FormatProposal with format ", *io_format); 85569983609Sbeveloper 85652a38012Sejakowatz // BBufferProducer::FormatProposal 8578c6a6096Sbeveloper request1.output = from; 8588c6a6096Sbeveloper request1.format = *io_format; 85934c72144SAxel Dörfler rv = QueryPort(from.port, PRODUCER_FORMAT_PROPOSAL, &request1, 86034c72144SAxel Dörfler sizeof(request1), &reply1, sizeof(reply1)); 8618c6a6096Sbeveloper if (rv != B_OK) { 86234c72144SAxel Dörfler ERROR("BMediaRoster::Connect: aborted after " 86334c72144SAxel Dörfler "BBufferProducer::FormatProposal, status = %#lx\n",rv); 86452a38012Sejakowatz return rv; 86552a38012Sejakowatz } 8668c6a6096Sbeveloper // reply1.format now contains the format proposed by the producer 8678c6a6096Sbeveloper 8688c6a6096Sbeveloper consumer_accept_format_request request2; 8698c6a6096Sbeveloper consumer_accept_format_reply reply2; 8708c6a6096Sbeveloper 87134c72144SAxel Dörfler PRINT_FORMAT("BMediaRoster::Connect calling " 87234c72144SAxel Dörfler "BBufferConsumer::AcceptFormat with format ", reply1.format); 87369983609Sbeveloper 8748c6a6096Sbeveloper // BBufferConsumer::AcceptFormat 8758c6a6096Sbeveloper request2.dest = to; 8768c6a6096Sbeveloper request2.format = reply1.format; 87734c72144SAxel Dörfler rv = QueryPort(to.port, CONSUMER_ACCEPT_FORMAT, &request2, 87834c72144SAxel Dörfler sizeof(request2), &reply2, sizeof(reply2)); 8798c6a6096Sbeveloper if (rv != B_OK) { 88034c72144SAxel Dörfler ERROR("BMediaRoster::Connect: aborted after " 88134c72144SAxel Dörfler "BBufferConsumer::AcceptFormat, status = %#lx\n",rv); 8828c6a6096Sbeveloper return rv; 8838c6a6096Sbeveloper } 8848c6a6096Sbeveloper // reply2.format now contains the format accepted by the consumer 8858c6a6096Sbeveloper 8868c6a6096Sbeveloper // BBufferProducer::PrepareToConnect 8878c6a6096Sbeveloper producer_prepare_to_connect_request request3; 8888c6a6096Sbeveloper producer_prepare_to_connect_reply reply3; 8898c6a6096Sbeveloper 89034c72144SAxel Dörfler PRINT_FORMAT("BMediaRoster::Connect calling " 89134c72144SAxel Dörfler "BBufferProducer::PrepareToConnect with format", reply2.format); 89269983609Sbeveloper 8938c6a6096Sbeveloper request3.source = from; 8948c6a6096Sbeveloper request3.destination = to; 8958c6a6096Sbeveloper request3.format = reply2.format; 89634c72144SAxel Dörfler strcpy(request3.name, "XXX some default name"); // TODO: fix this 89734c72144SAxel Dörfler rv = QueryPort(from.port, PRODUCER_PREPARE_TO_CONNECT, &request3, 89834c72144SAxel Dörfler sizeof(request3), &reply3, sizeof(reply3)); 8998c6a6096Sbeveloper if (rv != B_OK) { 90034c72144SAxel Dörfler ERROR("BMediaRoster::Connect: aborted after " 90134c72144SAxel Dörfler "BBufferProducer::PrepareToConnect, status = %#lx\n",rv); 9028c6a6096Sbeveloper return rv; 9038c6a6096Sbeveloper } 9048c6a6096Sbeveloper // reply3.format is still our pretty media format 9058c6a6096Sbeveloper // reply3.out_source the real source to be used for the connection 90634c72144SAxel Dörfler // reply3.name the name BBufferConsumer::Connected will see in the 90734c72144SAxel Dörfler // outInput->name argument 9088c6a6096Sbeveloper 9098c6a6096Sbeveloper // BBufferConsumer::Connected 9108c6a6096Sbeveloper consumer_connected_request request4; 9118c6a6096Sbeveloper consumer_connected_reply reply4; 9128c6a6096Sbeveloper status_t con_status; 9138c6a6096Sbeveloper 91434c72144SAxel Dörfler PRINT_FORMAT("BMediaRoster::Connect calling BBufferConsumer::Connected() " 91534c72144SAxel Dörfler "with format ", reply3.format); 91669983609Sbeveloper 91769983609Sbeveloper request4.input.node = destnode; 91869983609Sbeveloper request4.input.source = reply3.out_source; 91969983609Sbeveloper request4.input.destination = to; 92069983609Sbeveloper request4.input.format = reply3.format; 92169983609Sbeveloper strcpy(request4.input.name, reply3.name); 92269983609Sbeveloper 92334c72144SAxel Dörfler con_status = QueryPort(to.port, CONSUMER_CONNECTED, &request4, 92434c72144SAxel Dörfler sizeof(request4), &reply4, sizeof(reply4)); 9258c6a6096Sbeveloper if (con_status != B_OK) { 92634c72144SAxel Dörfler ERROR("BMediaRoster::Connect: aborting after " 92734c72144SAxel Dörfler "BBufferConsumer::Connected, status = %#lx\n",con_status); 9288c6a6096Sbeveloper // we do NOT return here! 9298c6a6096Sbeveloper } 93034c72144SAxel Dörfler // con_status contains the status code to be supplied to 93134c72144SAxel Dörfler // BBufferProducer::Connect's status argument 93234c72144SAxel Dörfler // reply4.input contains the media_input that describes the connection 93334c72144SAxel Dörfler // from the consumer point of view 9348c6a6096Sbeveloper 9358c6a6096Sbeveloper // BBufferProducer::Connect 9368c6a6096Sbeveloper producer_connect_request request5; 9378c6a6096Sbeveloper producer_connect_reply reply5; 9388c6a6096Sbeveloper 93934c72144SAxel Dörfler PRINT_FORMAT("BMediaRoster::Connect calling BBufferProducer::Connect with " 94034c72144SAxel Dörfler "format ", reply4.input.format); 94169983609Sbeveloper 9428c6a6096Sbeveloper request5.error = con_status; 9438c6a6096Sbeveloper request5.source = reply3.out_source; 9448c6a6096Sbeveloper request5.destination = reply4.input.destination; 94569983609Sbeveloper request5.format = reply4.input.format; 9468c6a6096Sbeveloper strcpy(request5.name, reply4.input.name); 94734c72144SAxel Dörfler rv = QueryPort(reply4.input.source.port, PRODUCER_CONNECT, &request5, 94834c72144SAxel Dörfler sizeof(request5), &reply5, sizeof(reply5)); 9498c6a6096Sbeveloper if (con_status != B_OK) { 9505ac4fbd7Sbeveloper ERROR("BMediaRoster::Connect: aborted\n"); 9518c6a6096Sbeveloper return con_status; 9528c6a6096Sbeveloper } 9538c6a6096Sbeveloper if (rv != B_OK) { 95434c72144SAxel Dörfler ERROR("BMediaRoster::Connect: aborted after BBufferProducer::Connect()" 95534c72144SAxel Dörfler ", status = %#lx\n",rv); 9568c6a6096Sbeveloper return rv; 9578c6a6096Sbeveloper } 9588c6a6096Sbeveloper // reply5.name contains the name assigned to the connection by the producer 9598c6a6096Sbeveloper 9608c6a6096Sbeveloper // initilize connection info 96169983609Sbeveloper *io_format = reply4.input.format; 9628c6a6096Sbeveloper *out_input = reply4.input; 9638c6a6096Sbeveloper out_output->node = sourcenode; 9648c6a6096Sbeveloper out_output->source = reply4.input.source; 9658c6a6096Sbeveloper out_output->destination = reply4.input.destination; 9668c6a6096Sbeveloper out_output->format = reply4.input.format; 9678c6a6096Sbeveloper strcpy(out_output->name, reply5.name); 9688c6a6096Sbeveloper 9698c6a6096Sbeveloper // the connection is now made 97069983609Sbeveloper printf("BMediaRoster::Connect connection established!\n"); 97169983609Sbeveloper PRINT_FORMAT(" format", *io_format); 97269983609Sbeveloper PRINT_INPUT(" input", *out_input); 97369983609Sbeveloper PRINT_OUTPUT(" output", *out_output); 9748c6a6096Sbeveloper 97534c72144SAxel Dörfler // TODO: register connection with server 97634c72144SAxel Dörfler // TODO: we should just send a notification, instead of republishing all 97734c72144SAxel Dörfler // endpoints 97876669a29Sbeveloper List<media_output> outlist; 97976669a29Sbeveloper List<media_input> inlist; 98034c72144SAxel Dörfler if (MediaRosterEx(this)->GetAllOutputs(out_output->node , &outlist) == B_OK) 9818b04ffc1Sbeveloper MediaRosterEx(this)->PublishOutputs(out_output->node , &outlist); 98234c72144SAxel Dörfler if (MediaRosterEx(this)->GetAllInputs(out_input->node , &inlist) == B_OK) 9838b04ffc1Sbeveloper MediaRosterEx(this)->PublishInputs(out_input->node, &inlist); 9848c6a6096Sbeveloper 98534c72144SAxel Dörfler // TODO: if (mute) BBufferProducer::EnableOutput(false) 9869e9417d2Sbeveloper if (in_flags & B_CONNECT_MUTED) { 9879e9417d2Sbeveloper } 9888c6a6096Sbeveloper 9899e9417d2Sbeveloper // send a notification 99034c72144SAxel Dörfler BPrivate::media::notifications::ConnectionMade(*out_input, *out_output, 99134c72144SAxel Dörfler *io_format); 9929e9417d2Sbeveloper 9938c6a6096Sbeveloper return B_OK; 9948c6a6096Sbeveloper }; 99552a38012Sejakowatz 99652a38012Sejakowatz 99752a38012Sejakowatz status_t 9989e9417d2Sbeveloper BMediaRoster::Disconnect(media_node_id source_nodeid, 99934c72144SAxel Dörfler const media_source& source, media_node_id destination_nodeid, 100052a38012Sejakowatz const media_destination& destination) 100152a38012Sejakowatz { 10029e9417d2Sbeveloper CALLED(); 100340f36b03Sbeveloper if (IS_INVALID_NODEID(source_nodeid)) { 10045ac4fbd7Sbeveloper ERROR("BMediaRoster::Disconnect: source media_node_id invalid\n"); 10059e9417d2Sbeveloper return B_MEDIA_BAD_SOURCE; 10069e9417d2Sbeveloper } 100740f36b03Sbeveloper if (IS_INVALID_NODEID(destination_nodeid)) { 10085ac4fbd7Sbeveloper ERROR("BMediaRoster::Disconnect: destination media_node_id invalid\n"); 10099e9417d2Sbeveloper return B_MEDIA_BAD_DESTINATION; 10109e9417d2Sbeveloper } 101140f36b03Sbeveloper if (IS_INVALID_SOURCE(source)) { 10125ac4fbd7Sbeveloper ERROR("BMediaRoster::Disconnect: media_source invalid\n"); 10139e9417d2Sbeveloper return B_MEDIA_BAD_SOURCE; 10149e9417d2Sbeveloper } 101540f36b03Sbeveloper if (IS_INVALID_DESTINATION(destination)) { 10165ac4fbd7Sbeveloper ERROR("BMediaRoster::Disconnect: media_destination invalid\n"); 10179e9417d2Sbeveloper return B_MEDIA_BAD_DESTINATION; 10189e9417d2Sbeveloper } 10199e9417d2Sbeveloper 10209e9417d2Sbeveloper producer_disconnect_request request2; 10219e9417d2Sbeveloper producer_disconnect_reply reply2; 10229e9417d2Sbeveloper consumer_disconnected_request request1; 10239e9417d2Sbeveloper consumer_disconnected_reply reply1; 10249e9417d2Sbeveloper status_t rv1, rv2; 10259e9417d2Sbeveloper 102634c72144SAxel Dörfler // TODO: we should ask the server if this connection really exists 10279e9417d2Sbeveloper 10289e9417d2Sbeveloper request1.source = source; 10299e9417d2Sbeveloper request1.destination = destination; 10309e9417d2Sbeveloper request2.source = source; 10319e9417d2Sbeveloper request2.destination = destination; 10329e9417d2Sbeveloper 103334c72144SAxel Dörfler rv1 = QueryPort(source.port, PRODUCER_DISCONNECT, &request1, 103434c72144SAxel Dörfler sizeof(request1), &reply1, sizeof(reply1)); 103534c72144SAxel Dörfler rv2 = QueryPort(destination.port, CONSUMER_DISCONNECTED, &request2, 103634c72144SAxel Dörfler sizeof(request2), &reply2, sizeof(reply2)); 10379e9417d2Sbeveloper 103834c72144SAxel Dörfler // TODO: unregister connection with server 103934c72144SAxel Dörfler // TODO: we should just send a notification, instead of republishing all 104034c72144SAxel Dörfler // endpoints 104176669a29Sbeveloper List<media_output> outlist; 104276669a29Sbeveloper List<media_input> inlist; 10439e9417d2Sbeveloper media_node sourcenode; 10449e9417d2Sbeveloper media_node destnode; 104534c72144SAxel Dörfler if (GetNodeFor(source_nodeid, &sourcenode) == B_OK) { 104665b73ae4SMarcus Overhagen if (!(sourcenode.kind & B_BUFFER_PRODUCER)) { 104734c72144SAxel Dörfler ERROR("BMediaRoster::Disconnect: source_nodeid %ld is not a " 104834c72144SAxel Dörfler "B_BUFFER_PRODUCER\n", source_nodeid); 104965b73ae4SMarcus Overhagen } 105034c72144SAxel Dörfler if (MediaRosterEx(this)->GetAllOutputs(sourcenode , &outlist) == B_OK) 10518b04ffc1Sbeveloper MediaRosterEx(this)->PublishOutputs(sourcenode , &outlist); 10529e9417d2Sbeveloper ReleaseNode(sourcenode); 10534f09fa2fSbeveloper } else { 105465b73ae4SMarcus Overhagen ERROR("BMediaRoster::Disconnect: GetNodeFor source_nodeid %ld failed\n", source_nodeid); 10554f09fa2fSbeveloper } 105634c72144SAxel Dörfler if (GetNodeFor(destination_nodeid, &destnode) == B_OK) { 105765b73ae4SMarcus Overhagen if (!(destnode.kind & B_BUFFER_CONSUMER)) { 105834c72144SAxel Dörfler ERROR("BMediaRoster::Disconnect: destination_nodeid %ld is not a " 105934c72144SAxel Dörfler "B_BUFFER_CONSUMER\n", destination_nodeid); 106065b73ae4SMarcus Overhagen } 106134c72144SAxel Dörfler if (MediaRosterEx(this)->GetAllInputs(destnode , &inlist) == B_OK) 10628b04ffc1Sbeveloper MediaRosterEx(this)->PublishInputs(destnode, &inlist); 10639e9417d2Sbeveloper ReleaseNode(destnode); 10644f09fa2fSbeveloper } else { 106534c72144SAxel Dörfler ERROR("BMediaRoster::Disconnect: GetNodeFor destination_nodeid %ld " 106634c72144SAxel Dörfler "failed\n", destination_nodeid); 10674f09fa2fSbeveloper } 10689e9417d2Sbeveloper 10699e9417d2Sbeveloper // send a notification 10709e9417d2Sbeveloper BPrivate::media::notifications::ConnectionBroken(source, destination); 10719e9417d2Sbeveloper 107234c72144SAxel Dörfler return rv1 != B_OK || rv2 != B_OK ? B_ERROR : B_OK; 107352a38012Sejakowatz } 107452a38012Sejakowatz 107534c72144SAxel Dörfler 107665b73ae4SMarcus Overhagen status_t 107765b73ae4SMarcus Overhagen BMediaRoster::Disconnect(const media_output& output, const media_input& input) 107865b73ae4SMarcus Overhagen { 107965b73ae4SMarcus Overhagen if (IS_INVALID_NODEID(output.node.node)) { 108065b73ae4SMarcus Overhagen printf("BMediaRoster::Disconnect: output.node.node %ld invalid\n", 108165b73ae4SMarcus Overhagen output.node.node); 108265b73ae4SMarcus Overhagen return B_MEDIA_BAD_SOURCE; 108365b73ae4SMarcus Overhagen } 108465b73ae4SMarcus Overhagen if (IS_INVALID_NODEID(input.node.node)) { 108565b73ae4SMarcus Overhagen printf("BMediaRoster::Disconnect: input.node.node %ld invalid\n", 108665b73ae4SMarcus Overhagen input.node.node); 108765b73ae4SMarcus Overhagen return B_MEDIA_BAD_DESTINATION; 108865b73ae4SMarcus Overhagen } 108965b73ae4SMarcus Overhagen if (!(output.node.kind & B_BUFFER_PRODUCER)) { 109034c72144SAxel Dörfler printf("BMediaRoster::Disconnect: output.node.kind 0x%lx is no " 109134c72144SAxel Dörfler "B_BUFFER_PRODUCER\n", output.node.kind); 109265b73ae4SMarcus Overhagen return B_MEDIA_BAD_SOURCE; 109365b73ae4SMarcus Overhagen } 109465b73ae4SMarcus Overhagen if (!(input.node.kind & B_BUFFER_CONSUMER)) { 109534c72144SAxel Dörfler printf("BMediaRoster::Disconnect: input.node.kind 0x%lx is no " 109634c72144SAxel Dörfler "B_BUFFER_PRODUCER\n", input.node.kind); 109765b73ae4SMarcus Overhagen return B_MEDIA_BAD_DESTINATION; 109865b73ae4SMarcus Overhagen } 109965b73ae4SMarcus Overhagen if (input.source.port != output.source.port) { 110034c72144SAxel Dörfler printf("BMediaRoster::Disconnect: input.source.port %ld doesn't match " 110134c72144SAxel Dörfler "output.source.port %ld\n", input.source.port, output.source.port); 110265b73ae4SMarcus Overhagen return B_MEDIA_BAD_SOURCE; 110365b73ae4SMarcus Overhagen } 110465b73ae4SMarcus Overhagen if (input.source.id != output.source.id) { 110534c72144SAxel Dörfler printf("BMediaRoster::Disconnect: input.source.id %ld doesn't match " 110634c72144SAxel Dörfler "output.source.id %ld\n", input.source.id, output.source.id); 110765b73ae4SMarcus Overhagen return B_MEDIA_BAD_SOURCE; 110865b73ae4SMarcus Overhagen } 110965b73ae4SMarcus Overhagen if (input.destination.port != output.destination.port) { 111034c72144SAxel Dörfler printf("BMediaRoster::Disconnect: input.destination.port %ld doesn't " 111134c72144SAxel Dörfler "match output.destination.port %ld\n", input.destination.port, 111234c72144SAxel Dörfler output.destination.port); 111365b73ae4SMarcus Overhagen return B_MEDIA_BAD_DESTINATION; 111465b73ae4SMarcus Overhagen } 111565b73ae4SMarcus Overhagen if (input.destination.id != output.destination.id) { 111634c72144SAxel Dörfler printf("BMediaRoster::Disconnect: input.destination.id %ld doesn't " 111734c72144SAxel Dörfler "match output.destination.id %ld\n", input.destination.id, 111834c72144SAxel Dörfler output.destination.id); 111965b73ae4SMarcus Overhagen return B_MEDIA_BAD_DESTINATION; 112065b73ae4SMarcus Overhagen } 112134c72144SAxel Dörfler 112234c72144SAxel Dörfler return Disconnect(output.node.node, output.source, input.node.node, 112334c72144SAxel Dörfler input.destination); 112465b73ae4SMarcus Overhagen } 112565b73ae4SMarcus Overhagen 112652a38012Sejakowatz 112752a38012Sejakowatz status_t 112834c72144SAxel Dörfler BMediaRoster::StartNode(const media_node& node, bigtime_t atPerformanceTime) 112952a38012Sejakowatz { 113052a38012Sejakowatz CALLED(); 11319e9417d2Sbeveloper if (node.node <= 0) 113252a38012Sejakowatz return B_MEDIA_BAD_NODE; 113352a38012Sejakowatz 113434c72144SAxel Dörfler TRACE("BMediaRoster::StartNode, node %ld, at perf %Ld\n", node.node, 113534c72144SAxel Dörfler atPerformanceTime); 11360e21b167Sbeveloper 11376396865dSbeveloper node_start_command command; 113834c72144SAxel Dörfler command.performance_time = atPerformanceTime; 113952a38012Sejakowatz 11406396865dSbeveloper return SendToPort(node.port, NODE_START, &command, sizeof(command)); 114152a38012Sejakowatz } 114252a38012Sejakowatz 114352a38012Sejakowatz 114452a38012Sejakowatz status_t 114534c72144SAxel Dörfler BMediaRoster::StopNode(const media_node& node, bigtime_t atPerformanceTime, 114652a38012Sejakowatz bool immediate) 114752a38012Sejakowatz { 114852a38012Sejakowatz CALLED(); 114940f36b03Sbeveloper if (IS_INVALID_NODE(node)) 115052a38012Sejakowatz return B_MEDIA_BAD_NODE; 115152a38012Sejakowatz 115234c72144SAxel Dörfler TRACE("BMediaRoster::StopNode, node %ld, at perf %Ld %s\n", node.node, 115334c72144SAxel Dörfler atPerformanceTime, immediate ? "NOW" : ""); 11540e21b167Sbeveloper 11556396865dSbeveloper node_stop_command command; 115634c72144SAxel Dörfler command.performance_time = atPerformanceTime; 11576396865dSbeveloper command.immediate = immediate; 115852a38012Sejakowatz 11596396865dSbeveloper return SendToPort(node.port, NODE_STOP, &command, sizeof(command)); 116052a38012Sejakowatz } 116152a38012Sejakowatz 116252a38012Sejakowatz 116352a38012Sejakowatz status_t 116434c72144SAxel Dörfler BMediaRoster::SeekNode(const media_node& node, bigtime_t toMediaTime, 116534c72144SAxel Dörfler bigtime_t atPerformanceTime) 116652a38012Sejakowatz { 116752a38012Sejakowatz CALLED(); 116840f36b03Sbeveloper if (IS_INVALID_NODE(node)) 116952a38012Sejakowatz return B_MEDIA_BAD_NODE; 117052a38012Sejakowatz 117134c72144SAxel Dörfler TRACE("BMediaRoster::SeekNode, node %ld, at perf %Ld, to perf %Ld\n", 117234c72144SAxel Dörfler node.node, atPerformanceTime, toMediaTime); 11730e21b167Sbeveloper 11746396865dSbeveloper node_seek_command command; 117534c72144SAxel Dörfler command.media_time = toMediaTime; 117634c72144SAxel Dörfler command.performance_time = atPerformanceTime; 117752a38012Sejakowatz 11786396865dSbeveloper return SendToPort(node.port, NODE_SEEK, &command, sizeof(command)); 117952a38012Sejakowatz } 118052a38012Sejakowatz 118152a38012Sejakowatz 118252a38012Sejakowatz status_t 118334c72144SAxel Dörfler BMediaRoster::StartTimeSource(const media_node& node, bigtime_t atRealTime) 118452a38012Sejakowatz { 118552a38012Sejakowatz CALLED(); 118660f15390Sbeveloper if (IS_SYSTEM_TIMESOURCE(node)) { 118734c72144SAxel Dörfler // TODO: debug this 11885ac4fbd7Sbeveloper //ERROR("BMediaRoster::StartTimeSource node %ld is system timesource\n", node.node); 118960f15390Sbeveloper return B_OK; 119060f15390Sbeveloper } 119192e575c1Sbeveloper // if (IS_SHADOW_TIMESOURCE(node)) { 119234c72144SAxel Dörfler // // TODO: debug this 119392e575c1Sbeveloper // ERROR("BMediaRoster::StartTimeSource node %ld is shadow timesource\n", node.node); 119492e575c1Sbeveloper // return B_OK; 119592e575c1Sbeveloper // } 119640f36b03Sbeveloper if (IS_INVALID_NODE(node)) { 11975ac4fbd7Sbeveloper ERROR("BMediaRoster::StartTimeSource node %ld invalid\n", node.node); 119852a38012Sejakowatz return B_MEDIA_BAD_NODE; 11990e21b167Sbeveloper } 12000e21b167Sbeveloper if ((node.kind & B_TIME_SOURCE) == 0) { 120134c72144SAxel Dörfler ERROR("BMediaRoster::StartTimeSource node %ld is no timesource\n", 120234c72144SAxel Dörfler node.node); 120352a38012Sejakowatz return B_MEDIA_BAD_NODE; 12040e21b167Sbeveloper } 12050e21b167Sbeveloper 120634c72144SAxel Dörfler TRACE("BMediaRoster::StartTimeSource, node %ld, at real %Ld\n", node.node, 120734c72144SAxel Dörfler at_real_time); 120852a38012Sejakowatz 120952a38012Sejakowatz BTimeSource::time_source_op_info msg; 121052a38012Sejakowatz msg.op = BTimeSource::B_TIMESOURCE_START; 121134c72144SAxel Dörfler msg.real_time = atRealTime; 121252a38012Sejakowatz 121352a38012Sejakowatz return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg)); 121452a38012Sejakowatz } 121552a38012Sejakowatz 121652a38012Sejakowatz 121752a38012Sejakowatz status_t 121834c72144SAxel Dörfler BMediaRoster::StopTimeSource(const media_node& node, bigtime_t atRealTime, 121952a38012Sejakowatz bool immediate) 122052a38012Sejakowatz { 122152a38012Sejakowatz CALLED(); 122260f15390Sbeveloper if (IS_SYSTEM_TIMESOURCE(node)) { 122334c72144SAxel Dörfler // TODO: debug this 12245ac4fbd7Sbeveloper //ERROR("BMediaRoster::StopTimeSource node %ld is system timesource\n", node.node); 122560f15390Sbeveloper return B_OK; 122660f15390Sbeveloper } 122792e575c1Sbeveloper // if (IS_SHADOW_TIMESOURCE(node)) { 122834c72144SAxel Dörfler // // TODO: debug this 122992e575c1Sbeveloper // ERROR("BMediaRoster::StopTimeSource node %ld is shadow timesource\n", node.node); 123092e575c1Sbeveloper // return B_OK; 123192e575c1Sbeveloper // } 123240f36b03Sbeveloper if (IS_INVALID_NODE(node)) { 12335ac4fbd7Sbeveloper ERROR("BMediaRoster::StopTimeSource node %ld invalid\n", node.node); 123452a38012Sejakowatz return B_MEDIA_BAD_NODE; 12350e21b167Sbeveloper } 12360e21b167Sbeveloper if ((node.kind & B_TIME_SOURCE) == 0) { 123734c72144SAxel Dörfler ERROR("BMediaRoster::StopTimeSource node %ld is no timesource\n", 123834c72144SAxel Dörfler node.node); 123952a38012Sejakowatz return B_MEDIA_BAD_NODE; 12400e21b167Sbeveloper } 12410e21b167Sbeveloper 124234c72144SAxel Dörfler TRACE("BMediaRoster::StopTimeSource, node %ld, at real %Ld %s\n", 124334c72144SAxel Dörfler node.node, atRealTime, immediate ? "NOW" : ""); 124452a38012Sejakowatz 124552a38012Sejakowatz BTimeSource::time_source_op_info msg; 124634c72144SAxel Dörfler msg.op = immediate ? BTimeSource::B_TIMESOURCE_STOP_IMMEDIATELY 124734c72144SAxel Dörfler : BTimeSource::B_TIMESOURCE_STOP; 124834c72144SAxel Dörfler msg.real_time = atRealTime; 124952a38012Sejakowatz 125052a38012Sejakowatz return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg)); 125152a38012Sejakowatz } 125252a38012Sejakowatz 125352a38012Sejakowatz 125452a38012Sejakowatz status_t 125552a38012Sejakowatz BMediaRoster::SeekTimeSource(const media_node& node, 125634c72144SAxel Dörfler bigtime_t toPerformanceTime, bigtime_t atRealTime) 125752a38012Sejakowatz { 125852a38012Sejakowatz CALLED(); 125960f15390Sbeveloper if (IS_SYSTEM_TIMESOURCE(node)) { 126034c72144SAxel Dörfler // TODO: debug this 12615ac4fbd7Sbeveloper // ERROR("BMediaRoster::SeekTimeSource node %ld is system timesource\n", node.node); 126260f15390Sbeveloper // you can't seek the system time source, but 126360f15390Sbeveloper // returning B_ERROR would break StampTV 126460f15390Sbeveloper return B_OK; 126560f15390Sbeveloper } 126692e575c1Sbeveloper // if (IS_SHADOW_TIMESOURCE(node)) { 126734c72144SAxel Dörfler // // TODO: debug this 126892e575c1Sbeveloper // ERROR("BMediaRoster::SeekTimeSource node %ld is shadow timesource\n", node.node); 126992e575c1Sbeveloper // return B_OK; 127092e575c1Sbeveloper // } 127140f36b03Sbeveloper if (IS_INVALID_NODE(node)) { 12725ac4fbd7Sbeveloper ERROR("BMediaRoster::SeekTimeSource node %ld invalid\n", node.node); 127352a38012Sejakowatz return B_MEDIA_BAD_NODE; 12740e21b167Sbeveloper } 12750e21b167Sbeveloper if ((node.kind & B_TIME_SOURCE) == 0) { 127634c72144SAxel Dörfler ERROR("BMediaRoster::SeekTimeSource node %ld is no timesource\n", 127734c72144SAxel Dörfler node.node); 127852a38012Sejakowatz return B_MEDIA_BAD_NODE; 12790e21b167Sbeveloper } 12800e21b167Sbeveloper 128134c72144SAxel Dörfler TRACE("BMediaRoster::SeekTimeSource, node %ld, at real %Ld, to perf %Ld\n", 128234c72144SAxel Dörfler node.node, atRealTime, toPerformanceTime); 128352a38012Sejakowatz 128452a38012Sejakowatz BTimeSource::time_source_op_info msg; 128552a38012Sejakowatz msg.op = BTimeSource::B_TIMESOURCE_SEEK; 128634c72144SAxel Dörfler msg.real_time = atRealTime; 128734c72144SAxel Dörfler msg.performance_time = toPerformanceTime; 128852a38012Sejakowatz 128952a38012Sejakowatz return write_port(node.port, TIMESOURCE_OP, &msg, sizeof(msg)); 129052a38012Sejakowatz } 129152a38012Sejakowatz 129252a38012Sejakowatz 129352a38012Sejakowatz status_t 129434c72144SAxel Dörfler BMediaRoster::SyncToNode(const media_node& node, bigtime_t atTime, 129552a38012Sejakowatz bigtime_t timeout) 129652a38012Sejakowatz { 129752a38012Sejakowatz UNIMPLEMENTED(); 129860f15390Sbeveloper return B_OK; 129952a38012Sejakowatz } 130052a38012Sejakowatz 130152a38012Sejakowatz 130252a38012Sejakowatz status_t 130334c72144SAxel Dörfler BMediaRoster::SetRunModeNode(const media_node& node, BMediaNode::run_mode mode) 130452a38012Sejakowatz { 130531cf24c1SMarcus Overhagen TRACE("BMediaRoster::SetRunModeNode, node %ld, mode %d\n", node.node, mode); 130640f36b03Sbeveloper if (IS_INVALID_NODE(node)) 130752a38012Sejakowatz return B_MEDIA_BAD_NODE; 130852a38012Sejakowatz 1309dfb2ad61Sbeveloper node_set_run_mode_command msg; 131052a38012Sejakowatz msg.mode = mode; 131152a38012Sejakowatz 131252a38012Sejakowatz return write_port(node.port, NODE_SET_RUN_MODE, &msg, sizeof(msg)); 131352a38012Sejakowatz } 131452a38012Sejakowatz 131552a38012Sejakowatz 131652a38012Sejakowatz status_t 131752a38012Sejakowatz BMediaRoster::PrerollNode(const media_node& node) 131852a38012Sejakowatz { 131952a38012Sejakowatz CALLED(); 132040f36b03Sbeveloper if (IS_INVALID_NODE(node)) 132152a38012Sejakowatz return B_MEDIA_BAD_NODE; 132252a38012Sejakowatz 132352a38012Sejakowatz char dummy; 132452a38012Sejakowatz return write_port(node.port, NODE_PREROLL, &dummy, sizeof(dummy)); 132552a38012Sejakowatz } 132652a38012Sejakowatz 132752a38012Sejakowatz 132852a38012Sejakowatz status_t 132934c72144SAxel Dörfler BMediaRoster::RollNode(const media_node& node, bigtime_t startPerformance, 133034c72144SAxel Dörfler bigtime_t stopPerformance, bigtime_t atMediaTime) 133152a38012Sejakowatz { 133252a38012Sejakowatz UNIMPLEMENTED(); 133352a38012Sejakowatz return B_ERROR; 133452a38012Sejakowatz } 133552a38012Sejakowatz 133652a38012Sejakowatz 133752a38012Sejakowatz status_t 133852a38012Sejakowatz BMediaRoster::SetProducerRunModeDelay(const media_node& node, 133934c72144SAxel Dörfler bigtime_t delay, BMediaNode::run_mode mode) 134052a38012Sejakowatz { 134134c72144SAxel Dörfler TRACE("BMediaRoster::SetProducerRunModeDelay, node %ld, delay %Ld, " 134234c72144SAxel Dörfler "mode %d\n", node.node, delay, mode); 134360f15390Sbeveloper if (IS_INVALID_NODE(node)) 134460f15390Sbeveloper return B_MEDIA_BAD_NODE; 134560f15390Sbeveloper if ((node.kind & B_BUFFER_PRODUCER) == 0) 134660f15390Sbeveloper return B_MEDIA_BAD_NODE; 134760f15390Sbeveloper 134860f15390Sbeveloper producer_set_run_mode_delay_command command; 134960f15390Sbeveloper command.mode = mode; 135060f15390Sbeveloper command.delay = delay; 135160f15390Sbeveloper 135234c72144SAxel Dörfler return SendToPort(node.port, PRODUCER_SET_RUN_MODE_DELAY, &command, 135334c72144SAxel Dörfler sizeof(command)); 135452a38012Sejakowatz } 135552a38012Sejakowatz 135652a38012Sejakowatz 135752a38012Sejakowatz status_t 135834c72144SAxel Dörfler BMediaRoster::SetProducerRate(const media_node& producer, int32 numer, 135952a38012Sejakowatz int32 denom) 136052a38012Sejakowatz { 136152a38012Sejakowatz CALLED(); 136240f36b03Sbeveloper if (IS_INVALID_NODE(producer)) 136352a38012Sejakowatz return B_MEDIA_BAD_NODE; 136452a38012Sejakowatz if ((producer.kind & B_BUFFER_PRODUCER) == 0) 136552a38012Sejakowatz return B_MEDIA_BAD_NODE; 136652a38012Sejakowatz 1367dfb2ad61Sbeveloper producer_set_play_rate_request msg; 1368dfb2ad61Sbeveloper producer_set_play_rate_reply reply; 136952a38012Sejakowatz status_t rv; 137052a38012Sejakowatz int32 code; 137152a38012Sejakowatz 137252a38012Sejakowatz msg.numer = numer; 137352a38012Sejakowatz msg.denom = denom; 137452a38012Sejakowatz msg.reply_port = _PortPool->GetPort(); 137552a38012Sejakowatz rv = write_port(producer.node, PRODUCER_SET_PLAY_RATE, &msg, sizeof(msg)); 137652a38012Sejakowatz if (rv != B_OK) { 137752a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 137852a38012Sejakowatz return rv; 137952a38012Sejakowatz } 138052a38012Sejakowatz rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); 138152a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 138252a38012Sejakowatz return (rv < B_OK) ? rv : reply.result; 138352a38012Sejakowatz } 138452a38012Sejakowatz 138552a38012Sejakowatz 138634c72144SAxel Dörfler /*! Nodes will have available inputs/outputs as long as they are capable 138734c72144SAxel Dörfler of accepting more connections. The node may create an additional 138834c72144SAxel Dörfler output or input as the currently available is taken into usage. 138934c72144SAxel Dörfler */ 139052a38012Sejakowatz status_t 139152a38012Sejakowatz BMediaRoster::GetLiveNodeInfo(const media_node& node, 139252a38012Sejakowatz live_node_info* out_live_info) 139352a38012Sejakowatz { 13949e9417d2Sbeveloper CALLED(); 13959e9417d2Sbeveloper if (out_live_info == NULL) 13969e9417d2Sbeveloper return B_BAD_VALUE; 139740f36b03Sbeveloper if (IS_INVALID_NODE(node)) 13989e9417d2Sbeveloper return B_MEDIA_BAD_NODE; 13999e9417d2Sbeveloper 14009e9417d2Sbeveloper server_get_live_node_info_request request; 14019e9417d2Sbeveloper server_get_live_node_info_reply reply; 14029e9417d2Sbeveloper status_t rv; 14039e9417d2Sbeveloper 14049e9417d2Sbeveloper request.node = node; 14059e9417d2Sbeveloper 140634c72144SAxel Dörfler rv = QueryServer(SERVER_GET_LIVE_NODE_INFO, &request, sizeof(request), 140734c72144SAxel Dörfler &reply, sizeof(reply)); 14089e9417d2Sbeveloper if (rv != B_OK) 14099e9417d2Sbeveloper return rv; 14109e9417d2Sbeveloper 14119e9417d2Sbeveloper *out_live_info = reply.live_info; 14129e9417d2Sbeveloper return B_OK; 141352a38012Sejakowatz } 141452a38012Sejakowatz 141552a38012Sejakowatz 141652a38012Sejakowatz status_t 141734c72144SAxel Dörfler BMediaRoster::GetLiveNodes(live_node_info* _liveNodes, int32* _totalCount, 141834c72144SAxel Dörfler const media_format* hasInput, const media_format* hasOutput, 141934c72144SAxel Dörfler const char* name, uint64 nodeKinds) 142052a38012Sejakowatz { 14219e9417d2Sbeveloper CALLED(); 142234c72144SAxel Dörfler if (_liveNodes == NULL || _totalCount == NULL || *_totalCount <= 0) 14239e9417d2Sbeveloper return B_BAD_VALUE; 14249e9417d2Sbeveloper 142534c72144SAxel Dörfler // TODO: we also support the wildcard search as GetDormantNodes does. 142634c72144SAxel Dörfler // This needs to be documented 14279e9417d2Sbeveloper 14289e9417d2Sbeveloper server_get_live_nodes_request request; 14299e9417d2Sbeveloper server_get_live_nodes_reply reply; 14309e9417d2Sbeveloper status_t rv; 14319e9417d2Sbeveloper 143234c72144SAxel Dörfler request.maxcount = *_totalCount; 143334c72144SAxel Dörfler request.has_input = hasInput != NULL; 143434c72144SAxel Dörfler if (hasInput != NULL) { 143534c72144SAxel Dörfler // TODO: we should not make a flat copy of media_format 143634c72144SAxel Dörfler request.inputformat = *hasInput; 143734c72144SAxel Dörfler } 143834c72144SAxel Dörfler request.has_output = hasOutput != NULL; 143934c72144SAxel Dörfler if (hasOutput != NULL) { 144034c72144SAxel Dörfler // TODO: we should not make a flat copy of media_format 144134c72144SAxel Dörfler request.outputformat = *hasOutput; 144234c72144SAxel Dörfler } 144334c72144SAxel Dörfler request.has_name = name != NULL; 144434c72144SAxel Dörfler if (name != NULL) { 14459e9417d2Sbeveloper int len = strlen(name); 14469e9417d2Sbeveloper len = min_c(len, (int)sizeof(request.name) - 1); 14479e9417d2Sbeveloper memcpy(request.name, name, len); 14489e9417d2Sbeveloper request.name[len] = 0; 14499e9417d2Sbeveloper } 145034c72144SAxel Dörfler request.require_kinds = nodeKinds; 14519e9417d2Sbeveloper 145234c72144SAxel Dörfler rv = QueryServer(SERVER_GET_LIVE_NODES, &request, sizeof(request), 145334c72144SAxel Dörfler &reply, sizeof(reply)); 14549e9417d2Sbeveloper if (rv != B_OK) { 14555ac4fbd7Sbeveloper ERROR("BMediaRoster::GetLiveNodes failed querying server\n"); 145634c72144SAxel Dörfler *_totalCount = 0; 14579e9417d2Sbeveloper return rv; 14589e9417d2Sbeveloper } 14599e9417d2Sbeveloper 14609e9417d2Sbeveloper if (reply.count > MAX_LIVE_INFO) { 146134c72144SAxel Dörfler live_node_info* liveInfo; 14629e9417d2Sbeveloper area_id clone; 14639e9417d2Sbeveloper 146434c72144SAxel Dörfler clone = clone_area("live_node_info clone", 146534c72144SAxel Dörfler reinterpret_cast<void **>(&liveInfo), B_ANY_ADDRESS, 146634c72144SAxel Dörfler B_READ_AREA | B_WRITE_AREA, reply.area); 14679e9417d2Sbeveloper if (clone < B_OK) { 146834c72144SAxel Dörfler ERROR("BMediaRoster::GetLiveNodes failed to clone area, %#lx\n", 146934c72144SAxel Dörfler clone); 14709e9417d2Sbeveloper delete_area(reply.area); 147134c72144SAxel Dörfler *_totalCount = 0; 147252a38012Sejakowatz return B_ERROR; 147352a38012Sejakowatz } 147452a38012Sejakowatz 14759e9417d2Sbeveloper for (int32 i = 0; i < reply.count; i++) { 147634c72144SAxel Dörfler _liveNodes[i] = liveInfo[i]; 14779e9417d2Sbeveloper } 14789e9417d2Sbeveloper 14799e9417d2Sbeveloper delete_area(clone); 14809e9417d2Sbeveloper delete_area(reply.area); 14819e9417d2Sbeveloper } else { 14829e9417d2Sbeveloper for (int32 i = 0; i < reply.count; i++) { 148334c72144SAxel Dörfler _liveNodes[i] = reply.live_info[i]; 14849e9417d2Sbeveloper } 14859e9417d2Sbeveloper } 148634c72144SAxel Dörfler *_totalCount = reply.count; 14879e9417d2Sbeveloper 14889e9417d2Sbeveloper return B_OK; 14899e9417d2Sbeveloper } 14909e9417d2Sbeveloper 149152a38012Sejakowatz 149252a38012Sejakowatz status_t 149352a38012Sejakowatz BMediaRoster::GetFreeInputsFor(const media_node& node, 149434c72144SAxel Dörfler media_input * out_free_inputs, int32 buf_num_inputs, 149534c72144SAxel Dörfler int32 * out_total_count, media_type filter_type) 149652a38012Sejakowatz { 14973620737cSbeveloper CALLED(); 14985ac4fbd7Sbeveloper if (IS_INVALID_NODE(node)) { 149934c72144SAxel Dörfler ERROR("BMediaRoster::GetFreeInputsFor: node %ld, port %ld invalid\n", 150034c72144SAxel Dörfler node.node, node.port); 15013620737cSbeveloper return B_MEDIA_BAD_NODE; 15025ac4fbd7Sbeveloper } 15035ac4fbd7Sbeveloper if ((node.kind & B_BUFFER_CONSUMER) == 0) { 150434c72144SAxel Dörfler ERROR("BMediaRoster::GetFreeInputsFor: node %ld, port %ld is not a " 150534c72144SAxel Dörfler "consumer\n", node.node, node.port); 15065ac4fbd7Sbeveloper return B_MEDIA_BAD_NODE; 15075ac4fbd7Sbeveloper } 15083620737cSbeveloper if (out_free_inputs == NULL || out_total_count == NULL) 15093620737cSbeveloper return B_BAD_VALUE; 15103620737cSbeveloper 151176669a29Sbeveloper List<media_input> list; 15123620737cSbeveloper media_input *input; 15133620737cSbeveloper status_t rv; 15143620737cSbeveloper 15151299bfb2Sbeveloper *out_total_count = 0; 15161299bfb2Sbeveloper 15178b04ffc1Sbeveloper rv = MediaRosterEx(this)->GetAllInputs(node, &list); 15183620737cSbeveloper if (B_OK != rv) 15193620737cSbeveloper return rv; 15203620737cSbeveloper 152134c72144SAxel Dörfler PRINT(4, "BMediaRoster::GetFreeInputsFor node %ld, max %ld, filter-type " 152234c72144SAxel Dörfler "%ld\n", node.node, buf_num_inputs, filter_type); 15235ac4fbd7Sbeveloper 152476669a29Sbeveloper int32 i; 1525b65a0ac5SJérôme Duval for (i = 0, list.Rewind(); list.GetNext(&input);) { 152634c72144SAxel Dörfler if (filter_type != B_MEDIA_UNKNOWN_TYPE 152734c72144SAxel Dörfler && filter_type != input->format.type) { 152834c72144SAxel Dörfler // media_type used, but doesn't match 152934c72144SAxel Dörfler continue; 153034c72144SAxel Dörfler } 153134c72144SAxel Dörfler if (input->source != media_source::null) { 153234c72144SAxel Dörfler // consumer source already connected 153334c72144SAxel Dörfler continue; 153434c72144SAxel Dörfler } 153534c72144SAxel Dörfler 15363620737cSbeveloper out_free_inputs[i] = *input; 15373620737cSbeveloper *out_total_count += 1; 15383620737cSbeveloper buf_num_inputs -= 1; 15395ac4fbd7Sbeveloper #if DEBUG >= 3 15405ac4fbd7Sbeveloper PRINT_OUTPUT(" input", out_free_inputs[i]); 15415ac4fbd7Sbeveloper #endif 15423620737cSbeveloper if (buf_num_inputs == 0) 15433620737cSbeveloper break; 1544b65a0ac5SJérôme Duval i++; 15453620737cSbeveloper } 15463620737cSbeveloper 15478b04ffc1Sbeveloper MediaRosterEx(this)->PublishInputs(node, &list); 15483620737cSbeveloper return B_OK; 154952a38012Sejakowatz } 155052a38012Sejakowatz 155152a38012Sejakowatz 155252a38012Sejakowatz status_t 155352a38012Sejakowatz BMediaRoster::GetConnectedInputsFor(const media_node& node, 155434c72144SAxel Dörfler media_input* out_active_inputs, int32 buf_num_inputs, 155552a38012Sejakowatz int32* out_total_count) 155652a38012Sejakowatz { 15573620737cSbeveloper CALLED(); 155840f36b03Sbeveloper if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_CONSUMER) == 0) 15593620737cSbeveloper return B_MEDIA_BAD_NODE; 15603620737cSbeveloper if (out_active_inputs == NULL || out_total_count == NULL) 15613620737cSbeveloper return B_BAD_VALUE; 15623620737cSbeveloper 156376669a29Sbeveloper List<media_input> list; 15643620737cSbeveloper media_input *input; 15653620737cSbeveloper status_t rv; 15663620737cSbeveloper 15671299bfb2Sbeveloper *out_total_count = 0; 15681299bfb2Sbeveloper 15698b04ffc1Sbeveloper rv = MediaRosterEx(this)->GetAllInputs(node, &list); 15703620737cSbeveloper if (B_OK != rv) 15713620737cSbeveloper return rv; 15723620737cSbeveloper 157334c72144SAxel Dörfler PRINT(4, "BMediaRoster::GetConnectedInputsFor node %ld, max %ld\n", 157434c72144SAxel Dörfler node.node, buf_num_inputs); 15755ac4fbd7Sbeveloper 157676669a29Sbeveloper int32 i; 1577b65a0ac5SJérôme Duval for (i = 0, list.Rewind(); list.GetNext(&input);) { 15783620737cSbeveloper if (input->source == media_source::null) 15793620737cSbeveloper continue; // consumer source not connected 15803620737cSbeveloper out_active_inputs[i] = *input; 15813620737cSbeveloper *out_total_count += 1; 15823620737cSbeveloper buf_num_inputs -= 1; 15835ac4fbd7Sbeveloper #if DEBUG >= 3 15845ac4fbd7Sbeveloper PRINT_OUTPUT(" input ", out_active_inputs[i]); 15855ac4fbd7Sbeveloper #endif 15863620737cSbeveloper if (buf_num_inputs == 0) 15873620737cSbeveloper break; 1588b65a0ac5SJérôme Duval i++; 15893620737cSbeveloper } 15903620737cSbeveloper 15918b04ffc1Sbeveloper MediaRosterEx(this)->PublishInputs(node, &list); 15923620737cSbeveloper return B_OK; 159352a38012Sejakowatz } 159452a38012Sejakowatz 159552a38012Sejakowatz 159652a38012Sejakowatz status_t 159734c72144SAxel Dörfler BMediaRoster::GetAllInputsFor(const media_node& node, media_input* out_inputs, 159834c72144SAxel Dörfler int32 buf_num_inputs, int32* out_total_count) 159952a38012Sejakowatz { 160052a38012Sejakowatz CALLED(); 160140f36b03Sbeveloper if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_CONSUMER) == 0) 160252a38012Sejakowatz return B_MEDIA_BAD_NODE; 160352a38012Sejakowatz if (out_inputs == NULL || out_total_count == NULL) 160452a38012Sejakowatz return B_BAD_VALUE; 160552a38012Sejakowatz 160676669a29Sbeveloper List<media_input> list; 16073620737cSbeveloper media_input *input; 160852a38012Sejakowatz status_t rv; 160952a38012Sejakowatz 16101299bfb2Sbeveloper *out_total_count = 0; 16111299bfb2Sbeveloper 16128b04ffc1Sbeveloper rv = MediaRosterEx(this)->GetAllInputs(node, &list); 16133620737cSbeveloper if (B_OK != rv) 16143620737cSbeveloper return rv; 16153620737cSbeveloper 161634c72144SAxel Dörfler PRINT(4, "BMediaRoster::GetAllInputsFor node %ld, max %ld\n", node.node, 161734c72144SAxel Dörfler buf_num_inputs); 16185ac4fbd7Sbeveloper 161976669a29Sbeveloper int32 i; 162076669a29Sbeveloper for (i = 0, list.Rewind(); list.GetNext(&input); i++) { 16213620737cSbeveloper out_inputs[i] = *input; 162252a38012Sejakowatz *out_total_count += 1; 16233620737cSbeveloper buf_num_inputs -= 1; 16245ac4fbd7Sbeveloper #if DEBUG >= 3 16255ac4fbd7Sbeveloper PRINT_OUTPUT(" input ", out_inputs[i]); 16265ac4fbd7Sbeveloper #endif 16273620737cSbeveloper if (buf_num_inputs == 0) 16283620737cSbeveloper break; 162952a38012Sejakowatz } 163052a38012Sejakowatz 16318b04ffc1Sbeveloper MediaRosterEx(this)->PublishInputs(node, &list); 16323620737cSbeveloper return B_OK; 163352a38012Sejakowatz } 163452a38012Sejakowatz 163552a38012Sejakowatz 163652a38012Sejakowatz status_t 163752a38012Sejakowatz BMediaRoster::GetFreeOutputsFor(const media_node& node, 163834c72144SAxel Dörfler media_output* out_free_outputs, int32 buf_num_outputs, 163934c72144SAxel Dörfler int32* out_total_count, media_type filter_type) 164052a38012Sejakowatz { 16413620737cSbeveloper CALLED(); 164240f36b03Sbeveloper if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0) 16433620737cSbeveloper return B_MEDIA_BAD_NODE; 16443620737cSbeveloper if (out_free_outputs == NULL || out_total_count == NULL) 16453620737cSbeveloper return B_BAD_VALUE; 16463620737cSbeveloper 164776669a29Sbeveloper List<media_output> list; 16483620737cSbeveloper media_output *output; 16493620737cSbeveloper status_t rv; 16503620737cSbeveloper 16511299bfb2Sbeveloper *out_total_count = 0; 16521299bfb2Sbeveloper 16538b04ffc1Sbeveloper rv = MediaRosterEx(this)->GetAllOutputs(node, &list); 16543620737cSbeveloper if (B_OK != rv) 16553620737cSbeveloper return rv; 16563620737cSbeveloper 165734c72144SAxel Dörfler PRINT(4, "BMediaRoster::GetFreeOutputsFor node %ld, max %ld, filter-type " 165834c72144SAxel Dörfler "%ld\n", node.node, buf_num_outputs, filter_type); 16595ac4fbd7Sbeveloper 166076669a29Sbeveloper int32 i; 1661b65a0ac5SJérôme Duval for (i = 0, list.Rewind(); list.GetNext(&output);) { 166234c72144SAxel Dörfler if (filter_type != B_MEDIA_UNKNOWN_TYPE 166334c72144SAxel Dörfler && filter_type != output->format.type) { 166434c72144SAxel Dörfler // media_type used, but doesn't match 166534c72144SAxel Dörfler continue; 166634c72144SAxel Dörfler } 166734c72144SAxel Dörfler if (output->destination != media_destination::null) { 166834c72144SAxel Dörfler // producer destination already connected 166934c72144SAxel Dörfler continue; 167034c72144SAxel Dörfler } 167134c72144SAxel Dörfler 16723620737cSbeveloper out_free_outputs[i] = *output; 16733620737cSbeveloper *out_total_count += 1; 16743620737cSbeveloper buf_num_outputs -= 1; 16755ac4fbd7Sbeveloper #if DEBUG >= 3 16765ac4fbd7Sbeveloper PRINT_OUTPUT(" output ", out_free_outputs[i]); 16775ac4fbd7Sbeveloper #endif 16783620737cSbeveloper if (buf_num_outputs == 0) 16793620737cSbeveloper break; 1680b65a0ac5SJérôme Duval i++; 16813620737cSbeveloper } 16823620737cSbeveloper 16838b04ffc1Sbeveloper MediaRosterEx(this)->PublishOutputs(node, &list); 16843620737cSbeveloper return B_OK; 168552a38012Sejakowatz } 168652a38012Sejakowatz 168752a38012Sejakowatz 168852a38012Sejakowatz status_t 168952a38012Sejakowatz BMediaRoster::GetConnectedOutputsFor(const media_node& node, 169034c72144SAxel Dörfler media_output* out_active_outputs, int32 buf_num_outputs, 169152a38012Sejakowatz int32* out_total_count) 169252a38012Sejakowatz { 16933620737cSbeveloper CALLED(); 169440f36b03Sbeveloper if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0) 16953620737cSbeveloper return B_MEDIA_BAD_NODE; 16963620737cSbeveloper if (out_active_outputs == NULL || out_total_count == NULL) 16973620737cSbeveloper return B_BAD_VALUE; 16983620737cSbeveloper 169976669a29Sbeveloper List<media_output> list; 17003620737cSbeveloper media_output *output; 17013620737cSbeveloper status_t rv; 17023620737cSbeveloper 17031299bfb2Sbeveloper *out_total_count = 0; 17041299bfb2Sbeveloper 17058b04ffc1Sbeveloper rv = MediaRosterEx(this)->GetAllOutputs(node, &list); 17063620737cSbeveloper if (B_OK != rv) 17073620737cSbeveloper return rv; 17083620737cSbeveloper 170934c72144SAxel Dörfler PRINT(4, "BMediaRoster::GetConnectedOutputsFor node %ld, max %ld\n", 171034c72144SAxel Dörfler node.node, buf_num_outputs); 17115ac4fbd7Sbeveloper 171276669a29Sbeveloper int32 i; 1713b65a0ac5SJérôme Duval for (i = 0, list.Rewind(); list.GetNext(&output);) { 171434c72144SAxel Dörfler if (output->destination == media_destination::null) { 171534c72144SAxel Dörfler // producer destination not connected 171634c72144SAxel Dörfler continue; 171734c72144SAxel Dörfler } 17183620737cSbeveloper out_active_outputs[i] = *output; 17193620737cSbeveloper *out_total_count += 1; 17203620737cSbeveloper buf_num_outputs -= 1; 17215ac4fbd7Sbeveloper #if DEBUG >= 3 17225ac4fbd7Sbeveloper PRINT_OUTPUT(" output ", out_active_outputs[i]); 17235ac4fbd7Sbeveloper #endif 17243620737cSbeveloper if (buf_num_outputs == 0) 17253620737cSbeveloper break; 1726b65a0ac5SJérôme Duval i++; 17273620737cSbeveloper } 17283620737cSbeveloper 17298b04ffc1Sbeveloper MediaRosterEx(this)->PublishOutputs(node, &list); 17303620737cSbeveloper return B_OK; 173152a38012Sejakowatz } 173252a38012Sejakowatz 173352a38012Sejakowatz 173452a38012Sejakowatz status_t 173552a38012Sejakowatz BMediaRoster::GetAllOutputsFor(const media_node& node, 173634c72144SAxel Dörfler media_output* out_outputs, int32 buf_num_outputs, int32* out_total_count) 173752a38012Sejakowatz { 173852a38012Sejakowatz CALLED(); 173940f36b03Sbeveloper if (IS_INVALID_NODE(node) || (node.kind & B_BUFFER_PRODUCER) == 0) 174052a38012Sejakowatz return B_MEDIA_BAD_NODE; 174152a38012Sejakowatz if (out_outputs == NULL || out_total_count == NULL) 174252a38012Sejakowatz return B_BAD_VALUE; 174352a38012Sejakowatz 174476669a29Sbeveloper List<media_output> list; 17453620737cSbeveloper media_output *output; 174652a38012Sejakowatz status_t rv; 174752a38012Sejakowatz 17481299bfb2Sbeveloper *out_total_count = 0; 17491299bfb2Sbeveloper 17508b04ffc1Sbeveloper rv = MediaRosterEx(this)->GetAllOutputs(node, &list); 17513620737cSbeveloper if (B_OK != rv) 17523620737cSbeveloper return rv; 17533620737cSbeveloper 175434c72144SAxel Dörfler PRINT(4, "BMediaRoster::GetAllOutputsFor node %ld, max %ld\n", node.node, 175534c72144SAxel Dörfler buf_num_outputs); 17565ac4fbd7Sbeveloper 175776669a29Sbeveloper int32 i; 175876669a29Sbeveloper for (i = 0, list.Rewind(); list.GetNext(&output); i++) { 17593620737cSbeveloper out_outputs[i] = *output; 176052a38012Sejakowatz *out_total_count += 1; 17613620737cSbeveloper buf_num_outputs -= 1; 17625ac4fbd7Sbeveloper #if DEBUG >= 3 17635ac4fbd7Sbeveloper PRINT_OUTPUT(" output ", out_outputs[i]); 17645ac4fbd7Sbeveloper #endif 17653620737cSbeveloper if (buf_num_outputs == 0) 17663620737cSbeveloper break; 176752a38012Sejakowatz } 176852a38012Sejakowatz 17698b04ffc1Sbeveloper MediaRosterEx(this)->PublishOutputs(node, &list); 17703620737cSbeveloper return B_OK; 177152a38012Sejakowatz } 177252a38012Sejakowatz 177352a38012Sejakowatz 177452a38012Sejakowatz status_t 177552a38012Sejakowatz BMediaRoster::StartWatching(const BMessenger& where) 177652a38012Sejakowatz { 1777eae26d3dSbeveloper CALLED(); 1778eae26d3dSbeveloper if (!where.IsValid()) { 17795ac4fbd7Sbeveloper ERROR("BMediaRoster::StartWatching: messenger invalid!\n"); 1780eae26d3dSbeveloper return B_BAD_VALUE; 1781eae26d3dSbeveloper } 178234c72144SAxel Dörfler return BPrivate::media::notifications::Register(where, media_node::null, 178334c72144SAxel Dörfler B_MEDIA_WILDCARD); 178452a38012Sejakowatz } 178552a38012Sejakowatz 178652a38012Sejakowatz 178752a38012Sejakowatz status_t 178834c72144SAxel Dörfler BMediaRoster::StartWatching(const BMessenger & where, int32 notificationType) 178952a38012Sejakowatz { 1790eae26d3dSbeveloper CALLED(); 1791eae26d3dSbeveloper if (!where.IsValid()) { 17925ac4fbd7Sbeveloper ERROR("BMediaRoster::StartWatching: messenger invalid!\n"); 1793eae26d3dSbeveloper return B_BAD_VALUE; 1794eae26d3dSbeveloper } 179534c72144SAxel Dörfler if (!BPrivate::media::notifications::IsValidNotificationRequest(false, 179634c72144SAxel Dörfler notificationType)) { 17975ac4fbd7Sbeveloper ERROR("BMediaRoster::StartWatching: notificationType invalid!\n"); 1798eae26d3dSbeveloper return B_BAD_VALUE; 1799eae26d3dSbeveloper } 180034c72144SAxel Dörfler return BPrivate::media::notifications::Register(where, media_node::null, 180134c72144SAxel Dörfler notificationType); 180252a38012Sejakowatz } 180352a38012Sejakowatz 180452a38012Sejakowatz 180552a38012Sejakowatz status_t 180634c72144SAxel Dörfler BMediaRoster::StartWatching(const BMessenger& where, const media_node& node, 180752a38012Sejakowatz int32 notificationType) 180852a38012Sejakowatz { 1809eae26d3dSbeveloper CALLED(); 1810eae26d3dSbeveloper if (!where.IsValid()) { 18115ac4fbd7Sbeveloper ERROR("BMediaRoster::StartWatching: messenger invalid!\n"); 1812eae26d3dSbeveloper return B_BAD_VALUE; 1813eae26d3dSbeveloper } 181440f36b03Sbeveloper if (IS_INVALID_NODE(node)) { 18155ac4fbd7Sbeveloper ERROR("BMediaRoster::StartWatching: node invalid!\n"); 1816eae26d3dSbeveloper return B_MEDIA_BAD_NODE; 1817eae26d3dSbeveloper } 181834c72144SAxel Dörfler if (!BPrivate::media::notifications::IsValidNotificationRequest(true, 181934c72144SAxel Dörfler notificationType)) { 18205ac4fbd7Sbeveloper ERROR("BMediaRoster::StartWatching: notificationType invalid!\n"); 1821eae26d3dSbeveloper return B_BAD_VALUE; 1822eae26d3dSbeveloper } 182334c72144SAxel Dörfler return BPrivate::media::notifications::Register(where, node, 182434c72144SAxel Dörfler notificationType); 182552a38012Sejakowatz } 182652a38012Sejakowatz 182752a38012Sejakowatz 182852a38012Sejakowatz status_t 182952a38012Sejakowatz BMediaRoster::StopWatching(const BMessenger& where) 183052a38012Sejakowatz { 1831eae26d3dSbeveloper CALLED(); 1832eae26d3dSbeveloper // messenger may already be invalid, so we don't check this 183334c72144SAxel Dörfler return BPrivate::media::notifications::Unregister(where, media_node::null, 183434c72144SAxel Dörfler B_MEDIA_WILDCARD); 183552a38012Sejakowatz } 183652a38012Sejakowatz 183752a38012Sejakowatz 183852a38012Sejakowatz status_t 183934c72144SAxel Dörfler BMediaRoster::StopWatching(const BMessenger& where, int32 notificationType) 184052a38012Sejakowatz { 1841eae26d3dSbeveloper CALLED(); 1842eae26d3dSbeveloper // messenger may already be invalid, so we don't check this 184334c72144SAxel Dörfler if (!BPrivate::media::notifications::IsValidNotificationRequest(false, 184434c72144SAxel Dörfler notificationType)) { 18455ac4fbd7Sbeveloper ERROR("BMediaRoster::StopWatching: notificationType invalid!\n"); 1846eae26d3dSbeveloper return B_BAD_VALUE; 1847eae26d3dSbeveloper } 184834c72144SAxel Dörfler return BPrivate::media::notifications::Unregister(where, media_node::null, 184934c72144SAxel Dörfler notificationType); 185052a38012Sejakowatz } 185152a38012Sejakowatz 185252a38012Sejakowatz 185352a38012Sejakowatz status_t 185434c72144SAxel Dörfler BMediaRoster::StopWatching(const BMessenger& where, const media_node& node, 185552a38012Sejakowatz int32 notificationType) 185652a38012Sejakowatz { 1857eae26d3dSbeveloper CALLED(); 1858eae26d3dSbeveloper // messenger may already be invalid, so we don't check this 185940f36b03Sbeveloper if (IS_INVALID_NODE(node)) { 18605ac4fbd7Sbeveloper ERROR("BMediaRoster::StopWatching: node invalid!\n"); 1861eae26d3dSbeveloper return B_MEDIA_BAD_NODE; 1862eae26d3dSbeveloper } 186334c72144SAxel Dörfler if (!BPrivate::media::notifications::IsValidNotificationRequest(true, 186434c72144SAxel Dörfler notificationType)) { 18655ac4fbd7Sbeveloper ERROR("BMediaRoster::StopWatching: notificationType invalid!\n"); 1866eae26d3dSbeveloper return B_BAD_VALUE; 1867eae26d3dSbeveloper } 186834c72144SAxel Dörfler return BPrivate::media::notifications::Unregister(where, node, 186934c72144SAxel Dörfler notificationType); 187052a38012Sejakowatz } 187152a38012Sejakowatz 187252a38012Sejakowatz 187352a38012Sejakowatz status_t 187452a38012Sejakowatz BMediaRoster::RegisterNode(BMediaNode* node) 187552a38012Sejakowatz { 187654187cc6Sbeveloper CALLED(); 187754187cc6Sbeveloper // addon-id = -1 (unused), addon-flavor-id = 0 (unused, too) 187854187cc6Sbeveloper return MediaRosterEx(this)->RegisterNode(node, -1, 0); 187954187cc6Sbeveloper } 188054187cc6Sbeveloper 188154187cc6Sbeveloper 188254187cc6Sbeveloper status_t 188334c72144SAxel Dörfler BMediaRosterEx::RegisterNode(BMediaNode* node, media_addon_id addonid, 188434c72144SAxel Dörfler int32 flavorid) 188554187cc6Sbeveloper { 188652a38012Sejakowatz CALLED(); 188752a38012Sejakowatz if (node == NULL) 188852a38012Sejakowatz return B_BAD_VALUE; 188952a38012Sejakowatz 189054187cc6Sbeveloper // some sanity check 189154187cc6Sbeveloper // I'm not sure if the media kit warrants to call BMediaNode::AddOn() here. 189254187cc6Sbeveloper // Perhaps we don't need it. 189354187cc6Sbeveloper { 18949e9417d2Sbeveloper BMediaAddOn *addon; 18959e9417d2Sbeveloper int32 addon_flavor_id; 18969e9417d2Sbeveloper media_addon_id addon_id; 18979e9417d2Sbeveloper addon_flavor_id = 0; 18989e9417d2Sbeveloper addon = node->AddOn(&addon_flavor_id); 18999e9417d2Sbeveloper addon_id = addon ? addon->AddonID() : -1; 190054187cc6Sbeveloper ASSERT(addonid == addon_id); 190154187cc6Sbeveloper ASSERT(flavorid == addon_flavor_id); 190254187cc6Sbeveloper } 190352a38012Sejakowatz 190454187cc6Sbeveloper status_t rv; 19059e9417d2Sbeveloper server_register_node_request request; 19069e9417d2Sbeveloper server_register_node_reply reply; 19079e9417d2Sbeveloper 190854187cc6Sbeveloper request.addon_id = addonid; 190954187cc6Sbeveloper request.addon_flavor_id = flavorid; 19109e9417d2Sbeveloper strcpy(request.name, node->Name()); 19119e9417d2Sbeveloper request.kinds = node->Kinds(); 19129e9417d2Sbeveloper request.port = node->ControlPort(); 19139e9417d2Sbeveloper request.team = team; 19149e9417d2Sbeveloper 191534c72144SAxel Dörfler TRACE("BMediaRoster::RegisterNode: sending SERVER_REGISTER_NODE: port " 191634c72144SAxel Dörfler "%ld, kinds 0x%Lx, team %ld, name '%s'\n", request.port, request.kinds, 191734c72144SAxel Dörfler request.team, request.name); 19181299bfb2Sbeveloper 191934c72144SAxel Dörfler rv = QueryServer(SERVER_REGISTER_NODE, &request, sizeof(request), &reply, 192034c72144SAxel Dörfler sizeof(reply)); 19219e9417d2Sbeveloper if (rv != B_OK) { 192234c72144SAxel Dörfler ERROR("BMediaRoster::RegisterNode: failed to register node %s (error " 192334c72144SAxel Dörfler "%#lx)\n", node->Name(), rv); 19249e9417d2Sbeveloper return rv; 19259e9417d2Sbeveloper } 19269e9417d2Sbeveloper 192734c72144SAxel Dörfler TRACE("BMediaRoster::RegisterNode: QueryServer SERVER_REGISTER_NODE " 192834c72144SAxel Dörfler "finished\n"); 19294295907bSbeveloper 19308b04ffc1Sbeveloper // we are a friend class of BMediaNode and initialize this member variable 19319e9417d2Sbeveloper node->fNodeID = reply.nodeid; 19329e9417d2Sbeveloper ASSERT(reply.nodeid == node->Node().node); 19339e9417d2Sbeveloper ASSERT(reply.nodeid == node->ID()); 19349e9417d2Sbeveloper 19359e9417d2Sbeveloper // call the callback 19369e9417d2Sbeveloper node->NodeRegistered(); 19373620737cSbeveloper 19384295907bSbeveloper TRACE("BMediaRoster::RegisterNode: NodeRegistered callback finished\n"); 19394295907bSbeveloper 194034c72144SAxel Dörfler // if the BMediaNode also inherits from BTimeSource, we need to call 194134c72144SAxel Dörfler // BTimeSource::FinishCreate() 19420e21b167Sbeveloper if (node->Kinds() & B_TIME_SOURCE) { 19430e21b167Sbeveloper BTimeSource *ts; 19440e21b167Sbeveloper ts = dynamic_cast<BTimeSource *>(node); 19450e21b167Sbeveloper if (ts) 19460e21b167Sbeveloper ts->FinishCreate(); 19470e21b167Sbeveloper } 19480e21b167Sbeveloper 19494295907bSbeveloper TRACE("BMediaRoster::RegisterNode: publishing inputs/outputs\n"); 19504295907bSbeveloper 19513620737cSbeveloper // register existing inputs and outputs with the 19523620737cSbeveloper // media_server, this allows GetLiveNodes() to work 19533620737cSbeveloper // with created, but unconnected nodes. 19544d2d96e0Sbeveloper // The node control loop might not be running, or might deadlock 19554d2d96e0Sbeveloper // if we send a message and wait for a reply here. 19564d2d96e0Sbeveloper // We have a pointer to the node, and thus call the functions directly 19574295907bSbeveloper 19583620737cSbeveloper if (node->Kinds() & B_BUFFER_PRODUCER) { 19594d2d96e0Sbeveloper BBufferProducer *bp; 19604d2d96e0Sbeveloper bp = dynamic_cast<BBufferProducer *>(node); 19614d2d96e0Sbeveloper if (bp) { 1962359ac306Sbeveloper List<media_output> list; 19634d2d96e0Sbeveloper if (B_OK == GetAllOutputs(bp, &list)) 1964359ac306Sbeveloper PublishOutputs(node->Node(), &list); 196521871f38Sbeveloper } 19664d2d96e0Sbeveloper } 196721871f38Sbeveloper if (node->Kinds() & B_BUFFER_CONSUMER) { 19684d2d96e0Sbeveloper BBufferConsumer *bc; 19694d2d96e0Sbeveloper bc = dynamic_cast<BBufferConsumer *>(node); 19704d2d96e0Sbeveloper if (bc) { 1971359ac306Sbeveloper List<media_input> list; 19724d2d96e0Sbeveloper if (B_OK == GetAllInputs(bc, &list)) 1973359ac306Sbeveloper PublishInputs(node->Node(), &list); 19743620737cSbeveloper } 19754d2d96e0Sbeveloper } 197621871f38Sbeveloper 19774295907bSbeveloper TRACE("BMediaRoster::RegisterNode: sending NodesCreated\n"); 19784295907bSbeveloper 19791299bfb2Sbeveloper BPrivate::media::notifications::NodesCreated(&reply.nodeid, 1); 19804295907bSbeveloper 19814295907bSbeveloper TRACE("BMediaRoster::RegisterNode: finished\n"); 19824295907bSbeveloper 1983570f7d04Sbeveloper /* 1984570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: registered node name '%s', id %ld, addon %ld, flavor %ld\n", node->Name(), node->ID(), addon_id, addon_flavor_id); 1985570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node this %p\n", node); 1986570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node fConsumerThis %p\n", node->fConsumerThis); 1987570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node fProducerThis %p\n", node->fProducerThis); 1988570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node fFileInterfaceThis %p\n", node->fFileInterfaceThis); 1989570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node fControllableThis %p\n", node->fControllableThis); 1990570f7d04Sbeveloper TRACE("BMediaRoster::RegisterNode: node fTimeSourceThis %p\n", node->fTimeSourceThis); 1991570f7d04Sbeveloper */ 19929e9417d2Sbeveloper return B_OK; 199352a38012Sejakowatz } 199452a38012Sejakowatz 199552a38012Sejakowatz 199652a38012Sejakowatz status_t 199752a38012Sejakowatz BMediaRoster::UnregisterNode(BMediaNode* node) 199852a38012Sejakowatz { 19999e9417d2Sbeveloper CALLED(); 20009e9417d2Sbeveloper if (node == NULL) 20019e9417d2Sbeveloper return B_BAD_VALUE; 20029e9417d2Sbeveloper 200360f15390Sbeveloper TRACE("BMediaRoster::UnregisterNode %ld (%p)\n", node->ID(), node); 200460f15390Sbeveloper 200586bce45bSbeveloper if (node->fKinds & NODE_KIND_NO_REFCOUNTING) { 200634c72144SAxel Dörfler TRACE("BMediaRoster::UnregisterNode, trying to unregister reference " 200734c72144SAxel Dörfler "counting disabled timesource, node %ld, port %ld, team %ld\n", 200834c72144SAxel Dörfler node->ID(), node->ControlPort(), team); 200986bce45bSbeveloper return B_OK; 201086bce45bSbeveloper } 20118b04ffc1Sbeveloper if (node->ID() == NODE_UNREGISTERED_ID) { 201234c72144SAxel Dörfler PRINT(1, "Warning: BMediaRoster::UnregisterNode: node id %ld, name " 201334c72144SAxel Dörfler "'%s' already unregistered\n", node->ID(), node->Name()); 20149e9417d2Sbeveloper return B_OK; 20159e9417d2Sbeveloper } 201654187cc6Sbeveloper if (node->fRefCount != 0) { 201734c72144SAxel Dörfler PRINT(1, "Warning: BMediaRoster::UnregisterNode: node id %ld, name " 201834c72144SAxel Dörfler "'%s' has local reference count of %ld\n", node->ID(), node->Name(), 201934c72144SAxel Dörfler node->fRefCount); 202054187cc6Sbeveloper // no return here, we continue and unregister! 202154187cc6Sbeveloper } 202254187cc6Sbeveloper 202334c72144SAxel Dörfler // Calling BMediaAddOn::GetConfigurationFor(BMediaNode *node, 202434c72144SAxel Dörfler // BMessage *config) if this node was instanciated by an add-on needs to 202534c72144SAxel Dörfler // be done *somewhere* 202654187cc6Sbeveloper // We can't do it here because it is already to late (destructor of the node 202754187cc6Sbeveloper // might have been called). 20289e9417d2Sbeveloper 20299e9417d2Sbeveloper server_unregister_node_request request; 20309e9417d2Sbeveloper server_unregister_node_reply reply; 20319e9417d2Sbeveloper status_t rv; 20329e9417d2Sbeveloper 20339e9417d2Sbeveloper request.nodeid = node->ID(); 20349e9417d2Sbeveloper request.team = team; 20359e9417d2Sbeveloper 20361299bfb2Sbeveloper // send a notification 20371299bfb2Sbeveloper BPrivate::media::notifications::NodesDeleted(&request.nodeid, 1); 20381299bfb2Sbeveloper 203934c72144SAxel Dörfler rv = QueryServer(SERVER_UNREGISTER_NODE, &request, sizeof(request), &reply, 204034c72144SAxel Dörfler sizeof(reply)); 20419e9417d2Sbeveloper if (rv != B_OK) { 204234c72144SAxel Dörfler ERROR("BMediaRoster::UnregisterNode: failed to unregister node id %ld, " 204334c72144SAxel Dörfler "name '%s' (error %#lx)\n", node->ID(), node->Name(), rv); 20449e9417d2Sbeveloper return rv; 20459e9417d2Sbeveloper } 20469e9417d2Sbeveloper 204754187cc6Sbeveloper if (reply.addonid != -1) { 204854187cc6Sbeveloper // Small problem here, we can't use DormantNodeManager::PutAddon(), as 204934c72144SAxel Dörfler // UnregisterNode() is called by a dormant node itself (by the 205034c72144SAxel Dörfler // destructor). 205154187cc6Sbeveloper // The add-on that contains the node needs to remain in memory until the 205254187cc6Sbeveloper // destructor execution is finished. 205354187cc6Sbeveloper // DormantNodeManager::PutAddonDelayed() will delay unloading. 205454187cc6Sbeveloper _DormantNodeManager->PutAddonDelayed(reply.addonid); 2055cf4e2277Sbeveloper 205634c72144SAxel Dörfler rv = MediaRosterEx(this)->DecrementAddonFlavorInstancesCount( 205734c72144SAxel Dörfler reply.addonid, reply.flavorid); 205854187cc6Sbeveloper if (rv != B_OK) { 205934c72144SAxel Dörfler ERROR("BMediaRoster::UnregisterNode: " 206034c72144SAxel Dörfler "DecrementAddonFlavorInstancesCount() failed\n"); 206154187cc6Sbeveloper // this is really a problem, but we can't fail now 206254187cc6Sbeveloper } 20638b04ffc1Sbeveloper } 20649e9417d2Sbeveloper 20651299bfb2Sbeveloper // we are a friend class of BMediaNode and invalidate this member variable 20668b04ffc1Sbeveloper node->fNodeID = NODE_UNREGISTERED_ID; 20679e9417d2Sbeveloper 20689e9417d2Sbeveloper return B_OK; 206952a38012Sejakowatz } 207052a38012Sejakowatz 207152a38012Sejakowatz 207234c72144SAxel Dörfler //! Thread safe for multiple calls to Roster() 207352a38012Sejakowatz /*static*/ BMediaRoster* 207452a38012Sejakowatz BMediaRoster::Roster(status_t* out_error) 207552a38012Sejakowatz { 207652a38012Sejakowatz static BLocker locker("BMediaRoster::Roster locker"); 207752a38012Sejakowatz locker.Lock(); 20788496c38aSbeveloper if (out_error) 20798496c38aSbeveloper *out_error = B_OK; 20809def3bf7SStephan Aßmus if (sDefaultInstance == NULL) { 20818496c38aSbeveloper status_t err; 20829def3bf7SStephan Aßmus sDefaultInstance = new (std::nothrow) BMediaRosterEx(&err); 20839def3bf7SStephan Aßmus if (sDefaultInstance == NULL) 2084a715f908SStephan Aßmus err = B_NO_MEMORY; 2085a715f908SStephan Aßmus else if (err != B_OK) { 20869def3bf7SStephan Aßmus if (sDefaultInstance) { 20879def3bf7SStephan Aßmus sDefaultInstance->Lock(); 20889def3bf7SStephan Aßmus sDefaultInstance->Quit(); 20899def3bf7SStephan Aßmus sDefaultInstance = NULL; 2090dcfb6bfcSJérôme Duval } 20918496c38aSbeveloper if (out_error) 20928496c38aSbeveloper *out_error = err; 20938496c38aSbeveloper } 209452a38012Sejakowatz } 209552a38012Sejakowatz locker.Unlock(); 20969def3bf7SStephan Aßmus return sDefaultInstance; 209752a38012Sejakowatz } 209852a38012Sejakowatz 209952a38012Sejakowatz 210052a38012Sejakowatz /*static*/ BMediaRoster* 210152a38012Sejakowatz BMediaRoster::CurrentRoster() 210252a38012Sejakowatz { 21039def3bf7SStephan Aßmus return sDefaultInstance; 210452a38012Sejakowatz } 210552a38012Sejakowatz 210652a38012Sejakowatz 210752a38012Sejakowatz status_t 210834c72144SAxel Dörfler BMediaRoster::SetTimeSourceFor(media_node_id node, media_node_id time_source) 210952a38012Sejakowatz { 2110aac800c2Sbeveloper CALLED(); 211140f36b03Sbeveloper if (IS_INVALID_NODEID(node) || IS_INVALID_NODEID(time_source)) 2112aac800c2Sbeveloper return B_BAD_VALUE; 2113aac800c2Sbeveloper 2114aac800c2Sbeveloper media_node clone; 2115aac800c2Sbeveloper status_t rv, result; 2116aac800c2Sbeveloper 211734c72144SAxel Dörfler TRACE("BMediaRoster::SetTimeSourceFor: node %ld will be assigned time " 211834c72144SAxel Dörfler "source %ld\n", node, time_source); 211934c72144SAxel Dörfler TRACE("BMediaRoster::SetTimeSourceFor: node %ld time source %ld enter\n", 212034c72144SAxel Dörfler node, time_source); 21215917dd5bSbeveloper 212286bce45bSbeveloper // we need to get a clone of the node to have a port id 2123aac800c2Sbeveloper rv = GetNodeFor(node, &clone); 2124aac800c2Sbeveloper if (rv != B_OK) { 212534c72144SAxel Dörfler ERROR("BMediaRoster::SetTimeSourceFor, GetNodeFor failed, node id " 212634c72144SAxel Dörfler "%ld\n", node); 212752a38012Sejakowatz return B_ERROR; 212852a38012Sejakowatz } 212952a38012Sejakowatz 213086bce45bSbeveloper // we just send the request to set time_source-id as timesource to the node, 213186bce45bSbeveloper // the NODE_SET_TIMESOURCE handler code will do the real assignment 2132aac800c2Sbeveloper result = B_OK; 2133aac800c2Sbeveloper node_set_timesource_command cmd; 2134aac800c2Sbeveloper cmd.timesource_id = time_source; 2135aac800c2Sbeveloper rv = SendToPort(clone.port, NODE_SET_TIMESOURCE, &cmd, sizeof(cmd)); 2136aac800c2Sbeveloper if (rv != B_OK) { 213734c72144SAxel Dörfler ERROR("BMediaRoster::SetTimeSourceFor, sending NODE_SET_TIMESOURCE " 213834c72144SAxel Dörfler "failed, node id %ld\n", node); 2139aac800c2Sbeveloper result = B_ERROR; 2140aac800c2Sbeveloper } 2141aac800c2Sbeveloper 214260f15390Sbeveloper // we release the clone 2143aac800c2Sbeveloper rv = ReleaseNode(clone); 2144aac800c2Sbeveloper if (rv != B_OK) { 214534c72144SAxel Dörfler ERROR("BMediaRoster::SetTimeSourceFor, ReleaseNode failed, node id " 214634c72144SAxel Dörfler "%ld\n", node); 2147aac800c2Sbeveloper result = B_ERROR; 2148aac800c2Sbeveloper } 2149aac800c2Sbeveloper 215034c72144SAxel Dörfler TRACE("BMediaRoster::SetTimeSourceFor: node %ld time source %ld leave\n", 215134c72144SAxel Dörfler node, time_source); 21525917dd5bSbeveloper 2153aac800c2Sbeveloper return result; 2154aac800c2Sbeveloper } 2155aac800c2Sbeveloper 215652a38012Sejakowatz 215752a38012Sejakowatz status_t 215834c72144SAxel Dörfler BMediaRoster::GetParameterWebFor(const media_node& node, BParameterWeb** _web) 215952a38012Sejakowatz { 216028ad138aSbeveloper CALLED(); 216134c72144SAxel Dörfler if (_web == NULL) 216228ad138aSbeveloper return B_BAD_VALUE; 216328ad138aSbeveloper if (IS_INVALID_NODE(node)) 216428ad138aSbeveloper return B_MEDIA_BAD_NODE; 216528ad138aSbeveloper if ((node.kind & B_CONTROLLABLE) == 0) 216628ad138aSbeveloper return B_MEDIA_BAD_NODE; 216728ad138aSbeveloper 216828ad138aSbeveloper controllable_get_parameter_web_request request; 216928ad138aSbeveloper controllable_get_parameter_web_reply reply; 217034c72144SAxel Dörfler int32 requestsize[] = {B_PAGE_SIZE, 4 * B_PAGE_SIZE, 16 * B_PAGE_SIZE, 217134c72144SAxel Dörfler 64 * B_PAGE_SIZE, 128 * B_PAGE_SIZE, 256 * B_PAGE_SIZE, 0}; 217228ad138aSbeveloper int32 size; 217328ad138aSbeveloper 217434c72144SAxel Dörfler // TODO: it might be better to query the node for the (current) parameter 217534c72144SAxel Dörfler // size first 217628ad138aSbeveloper for (int i = 0; (size = requestsize[i]) != 0; i++) { 217728ad138aSbeveloper status_t rv; 217828ad138aSbeveloper area_id area; 217928ad138aSbeveloper void *data; 218034c72144SAxel Dörfler area = create_area("parameter web data", &data, B_ANY_ADDRESS, size, 218134c72144SAxel Dörfler B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); 218228ad138aSbeveloper if (area < B_OK) { 218334c72144SAxel Dörfler ERROR("BMediaRoster::GetParameterWebFor couldn't create area of " 218434c72144SAxel Dörfler "size %ld\n", size); 218528ad138aSbeveloper return B_ERROR; 218628ad138aSbeveloper } 218734c72144SAxel Dörfler request.max_size = size; 218828ad138aSbeveloper request.area = area; 218934c72144SAxel Dörfler rv = QueryPort(node.port, CONTROLLABLE_GET_PARAMETER_WEB, &request, 219034c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 219128ad138aSbeveloper if (rv != B_OK) { 219234c72144SAxel Dörfler ERROR("BMediaRoster::GetParameterWebFor " 219334c72144SAxel Dörfler "CONTROLLABLE_GET_PARAMETER_WEB failed\n"); 219428ad138aSbeveloper delete_area(area); 219528ad138aSbeveloper return B_ERROR; 219628ad138aSbeveloper } 219728ad138aSbeveloper if (reply.size == 0) { 219828ad138aSbeveloper // no parameter web available 219934c72144SAxel Dörfler // TODO: should we return an error? 220034c72144SAxel Dörfler ERROR("BMediaRoster::GetParameterWebFor node %ld has no parameter " 220134c72144SAxel Dörfler "web\n", node.node); 220234c72144SAxel Dörfler *_web = new (std::nothrow) BParameterWeb(); 220328ad138aSbeveloper delete_area(area); 220434c72144SAxel Dörfler return *_web != NULL ? B_OK : B_NO_MEMORY; 220552a38012Sejakowatz } 220628ad138aSbeveloper if (reply.size > 0) { 220728ad138aSbeveloper // we got a flattened parameter web! 220834c72144SAxel Dörfler *_web = new (std::nothrow) BParameterWeb(); 220934c72144SAxel Dörfler if (*_web == NULL) 2210a715f908SStephan Aßmus rv = B_NO_MEMORY; 2211a715f908SStephan Aßmus else { 221234c72144SAxel Dörfler printf("BMediaRoster::GetParameterWebFor Unflattening %ld " 221334c72144SAxel Dörfler "bytes, 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx\n", 221434c72144SAxel Dörfler reply.size, ((uint32*)data)[0], ((uint32*)data)[1], 221534c72144SAxel Dörfler ((uint32*)data)[2], ((uint32*)data)[3]); 221628ad138aSbeveloper 221734c72144SAxel Dörfler rv = (*_web)->Unflatten(reply.code, data, reply.size); 2218a715f908SStephan Aßmus } 221928ad138aSbeveloper if (rv != B_OK) { 222034c72144SAxel Dörfler ERROR("BMediaRoster::GetParameterWebFor Unflatten failed, " 222134c72144SAxel Dörfler "%s\n", strerror(rv)); 222234c72144SAxel Dörfler delete *_web; 222328ad138aSbeveloper } 222428ad138aSbeveloper delete_area(area); 2225a715f908SStephan Aßmus return rv; 222628ad138aSbeveloper } 222728ad138aSbeveloper delete_area(area); 222828ad138aSbeveloper ASSERT(reply.size == -1); 222928ad138aSbeveloper // parameter web data was too large 223028ad138aSbeveloper // loop and try a larger size 223128ad138aSbeveloper } 223234c72144SAxel Dörfler ERROR("BMediaRoster::GetParameterWebFor node %ld has no parameter web " 223334c72144SAxel Dörfler "larger than %ld\n", node.node, size); 223428ad138aSbeveloper return B_ERROR; 223528ad138aSbeveloper } 223652a38012Sejakowatz 223752a38012Sejakowatz 223852a38012Sejakowatz status_t 223934c72144SAxel Dörfler BMediaRoster::StartControlPanel(const media_node& node, BMessenger* _messenger) 224052a38012Sejakowatz { 2241999cd0acSMaurice Kalinowski CALLED(); 2242999cd0acSMaurice Kalinowski 2243999cd0acSMaurice Kalinowski controllable_start_control_panel_request request; 2244999cd0acSMaurice Kalinowski controllable_start_control_panel_reply reply; 2245999cd0acSMaurice Kalinowski 2246999cd0acSMaurice Kalinowski request.node = node; 2247999cd0acSMaurice Kalinowski 2248999cd0acSMaurice Kalinowski status_t rv; 224934c72144SAxel Dörfler rv = QueryPort(node.port, CONTROLLABLE_START_CONTROL_PANEL, &request, 225034c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 2251999cd0acSMaurice Kalinowski if (rv != B_OK) 2252999cd0acSMaurice Kalinowski return rv; 2253999cd0acSMaurice Kalinowski 225434c72144SAxel Dörfler if (reply.team != -1 && _messenger != NULL) 225534c72144SAxel Dörfler *_messenger = BMessenger(NULL, reply.team); 2256999cd0acSMaurice Kalinowski 2257999cd0acSMaurice Kalinowski return B_OK; 225852a38012Sejakowatz } 225952a38012Sejakowatz 226052a38012Sejakowatz 226152a38012Sejakowatz status_t 226234c72144SAxel Dörfler BMediaRoster::GetDormantNodes(dormant_node_info* _info, int32* _count, 226334c72144SAxel Dörfler const media_format* hasInput, const media_format* hasOutput, 226434c72144SAxel Dörfler const char* name, uint64 requireKinds, uint64 denyKinds) 226552a38012Sejakowatz { 226652a38012Sejakowatz CALLED(); 226734c72144SAxel Dörfler if (_info == NULL || _count == NULL || *_count <= 0) 226852a38012Sejakowatz return B_BAD_VALUE; 226952a38012Sejakowatz 227052a38012Sejakowatz xfer_server_get_dormant_nodes msg; 227152a38012Sejakowatz port_id port; 227252a38012Sejakowatz status_t rv; 227352a38012Sejakowatz 22744295907bSbeveloper port = find_port(MEDIA_SERVER_PORT_NAME); 227552a38012Sejakowatz if (port <= B_OK) 227652a38012Sejakowatz return B_ERROR; 227752a38012Sejakowatz 227834c72144SAxel Dörfler msg.maxcount = *_count; 227934c72144SAxel Dörfler msg.has_input = hasInput != NULL; 228034c72144SAxel Dörfler if (hasInput != NULL) { 228134c72144SAxel Dörfler // TODO: we should not make a flat copy of media_format 228234c72144SAxel Dörfler msg.inputformat = *hasInput; 228334c72144SAxel Dörfler } 228434c72144SAxel Dörfler msg.has_output = hasOutput != NULL; 228534c72144SAxel Dörfler if (hasOutput != NULL) { 228634c72144SAxel Dörfler // TODO: we should not make a flat copy of media_format 228734c72144SAxel Dörfler msg.outputformat = *hasOutput; 228834c72144SAxel Dörfler } 228934c72144SAxel Dörfler 229034c72144SAxel Dörfler msg.has_name = name != NULL; 229134c72144SAxel Dörfler if (name != NULL) { 22929e9417d2Sbeveloper int len = strlen(name); 22939e9417d2Sbeveloper len = min_c(len, (int)sizeof(msg.name) - 1); 229452a38012Sejakowatz memcpy(msg.name, name, len); 229552a38012Sejakowatz msg.name[len] = 0; 229652a38012Sejakowatz } 229734c72144SAxel Dörfler msg.require_kinds = requireKinds; 229834c72144SAxel Dörfler msg.deny_kinds = denyKinds; 229952a38012Sejakowatz msg.reply_port = _PortPool->GetPort(); 230052a38012Sejakowatz 230152a38012Sejakowatz rv = write_port(port, SERVER_GET_DORMANT_NODES, &msg, sizeof(msg)); 230252a38012Sejakowatz if (rv != B_OK) { 230352a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 230452a38012Sejakowatz return rv; 230552a38012Sejakowatz } 230652a38012Sejakowatz 230752a38012Sejakowatz xfer_server_get_dormant_nodes_reply reply; 230852a38012Sejakowatz int32 code; 230952a38012Sejakowatz 231052a38012Sejakowatz rv = read_port(msg.reply_port, &code, &reply, sizeof(reply)); 231152a38012Sejakowatz if (rv < B_OK) { 231252a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 231352a38012Sejakowatz return rv; 231452a38012Sejakowatz } 231552a38012Sejakowatz 231634c72144SAxel Dörfler *_count = reply.count; 231752a38012Sejakowatz 231834c72144SAxel Dörfler if (*_count > 0) { 231934c72144SAxel Dörfler rv = read_port(msg.reply_port, &code, _info, 232034c72144SAxel Dörfler *_count * sizeof(dormant_node_info)); 232152a38012Sejakowatz if (rv < B_OK) 232252a38012Sejakowatz reply.result = rv; 232352a38012Sejakowatz } 232452a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 232552a38012Sejakowatz 232652a38012Sejakowatz return reply.result; 232752a38012Sejakowatz } 232852a38012Sejakowatz 232934c72144SAxel Dörfler /*! This function is used to do the real work of instantiating a dormant node. 233034c72144SAxel Dörfler It is either called by the media_addon_server to instantiate a global node, 233134c72144SAxel Dörfler or it gets called from BMediaRoster::InstantiateDormantNode() to create a 233234c72144SAxel Dörfler local one. 233334c72144SAxel Dörfler 233434c72144SAxel Dörfler Checks concerning global/local are not done here. 23358b04ffc1Sbeveloper */ 233652a38012Sejakowatz status_t 233734c72144SAxel Dörfler BMediaRosterEx::InstantiateDormantNode(media_addon_id addonID, int32 flavorID, 233834c72144SAxel Dörfler team_id creator, media_node *_node) 233952a38012Sejakowatz { 234054187cc6Sbeveloper // This function is always called from the correct context, if the node 234154187cc6Sbeveloper // is supposed to be global, it is called from the media_addon_server. 234254187cc6Sbeveloper 234352a38012Sejakowatz // if B_FLAVOR_IS_GLOBAL, we need to use the BMediaAddOn object that 234452a38012Sejakowatz // resides in the media_addon_server 234552a38012Sejakowatz 23468b04ffc1Sbeveloper // RegisterNode() must be called for nodes instantiated from add-ons, 23478b04ffc1Sbeveloper // since the media kit warrants that it's done automatically. 234852a38012Sejakowatz 234934c72144SAxel Dörfler // addonID Indicates the ID number of the media add-on in which the 235034c72144SAxel Dörfler // node resides. 235134c72144SAxel Dörfler // flavorID Indicates the internal ID number that the add-on uses to 235234c72144SAxel Dörfler // identify the flavor, this is the number that was published 235334c72144SAxel Dörfler // by BMediaAddOn::GetFlavorAt() in the 23548b04ffc1Sbeveloper // flavor_info::internal_id field. 235534c72144SAxel Dörfler // creator The creator team is -1 if nodes are created locally. If 235634c72144SAxel Dörfler // created globally, it will contain (while called in 235734c72144SAxel Dörfler // media_addon_server context) the team-id of the team that 235834c72144SAxel Dörfler // requested the instantiation. 23598b04ffc1Sbeveloper 236034c72144SAxel Dörfler TRACE("BMediaRosterEx::InstantiateDormantNode: addonID %ld, flavorID " 236134c72144SAxel Dörfler "%ld\n", addonID, flavorID); 23628b04ffc1Sbeveloper 23638b04ffc1Sbeveloper // Get flavor_info from the server 236434c72144SAxel Dörfler dormant_flavor_info info; 23658c6a6096Sbeveloper status_t rv; 236634c72144SAxel Dörfler rv = GetDormantFlavorInfo(addonID, flavorID, &info); 23678b04ffc1Sbeveloper if (rv != B_OK) { 236834c72144SAxel Dörfler ERROR("BMediaRosterEx::InstantiateDormantNode error: failed to get " 236934c72144SAxel Dörfler "dormant_flavor_info for addon-id %ld, flavor-id %ld\n", addonID, 237034c72144SAxel Dörfler flavorID); 237152a38012Sejakowatz return B_ERROR; 237252a38012Sejakowatz } 23738b04ffc1Sbeveloper 2374*1ecccf18SFrançois Revol ASSERT(info.internal_id == flavorID); 23758b04ffc1Sbeveloper 23768b04ffc1Sbeveloper // load the BMediaAddOn object 23778b04ffc1Sbeveloper BMediaAddOn* addon; 237834c72144SAxel Dörfler addon = _DormantNodeManager->GetAddon(addonID); 237934c72144SAxel Dörfler if (addon == NULL) { 23805ac4fbd7Sbeveloper ERROR("BMediaRosterEx::InstantiateDormantNode: GetAddon failed\n"); 23818b04ffc1Sbeveloper return B_ERROR; 23828b04ffc1Sbeveloper } 23838b04ffc1Sbeveloper 238454187cc6Sbeveloper // Now we need to try to increment the use count of this addon flavor 238554187cc6Sbeveloper // in the server. This can fail if the total number instances of this 238654187cc6Sbeveloper // flavor is limited. 238734c72144SAxel Dörfler rv = IncrementAddonFlavorInstancesCount(addonID, flavorID); 238854187cc6Sbeveloper if (rv != B_OK) { 238934c72144SAxel Dörfler ERROR("BMediaRosterEx::InstantiateDormantNode error: can't create " 239034c72144SAxel Dörfler "more nodes for addon-id %ld, flavor-id %ld\n", addonID, flavorID); 239154187cc6Sbeveloper // Put the addon back into the pool 239234c72144SAxel Dörfler _DormantNodeManager->PutAddon(addonID); 239354187cc6Sbeveloper return B_ERROR; 239454187cc6Sbeveloper } 239554187cc6Sbeveloper 23968b04ffc1Sbeveloper BMessage config; 239734c72144SAxel Dörfler rv = LoadNodeConfiguration(addonID, flavorID, &config); 239854187cc6Sbeveloper if (rv != B_OK) { 239934c72144SAxel Dörfler ERROR("BMediaRosterEx::InstantiateDormantNode: couldn't load " 240034c72144SAxel Dörfler "configuration for addon-id %ld, flavor-id %ld\n", addonID, 240134c72144SAxel Dörfler flavorID); 240254187cc6Sbeveloper // do not return, this is a minor problem, not a reason to fail 240354187cc6Sbeveloper } 24048b04ffc1Sbeveloper 240534c72144SAxel Dörfler status_t status = B_OK; 240634c72144SAxel Dörfler BMediaNode* node = addon->InstantiateNodeFor(&info, &config, &status); 240734c72144SAxel Dörfler if (node == NULL) { 240834c72144SAxel Dörfler ERROR("BMediaRosterEx::InstantiateDormantNode: InstantiateNodeFor " 240934c72144SAxel Dörfler "failed\n"); 24108b04ffc1Sbeveloper 241154187cc6Sbeveloper // Put the addon back into the pool 241234c72144SAxel Dörfler _DormantNodeManager->PutAddon(addonID); 241334c72144SAxel Dörfler 241454187cc6Sbeveloper // We must decrement the use count of this addon flavor in the 241554187cc6Sbeveloper // server to compensate the increment done in the beginning. 241634c72144SAxel Dörfler rv = DecrementAddonFlavorInstancesCount(addonID, flavorID); 241754187cc6Sbeveloper if (rv != B_OK) { 241834c72144SAxel Dörfler ERROR("BMediaRosterEx::InstantiateDormantNode: DecrementAddon" 241934c72144SAxel Dörfler "FlavorInstancesCount failed\n"); 242016b7eea4Sbeveloper } 242134c72144SAxel Dörfler return status != B_OK ? status : B_ERROR; 242254187cc6Sbeveloper } 242354187cc6Sbeveloper 242434c72144SAxel Dörfler rv = RegisterNode(node, addonID, flavorID); 24258c6a6096Sbeveloper if (rv != B_OK) { 24265ac4fbd7Sbeveloper ERROR("BMediaRosterEx::InstantiateDormantNode: RegisterNode failed\n"); 24278c6a6096Sbeveloper delete node; 242854187cc6Sbeveloper // Put the addon back into the pool 242934c72144SAxel Dörfler _DormantNodeManager->PutAddon(addonID); 243054187cc6Sbeveloper // We must decrement the use count of this addon flavor in the 243154187cc6Sbeveloper // server to compensate the increment done in the beginning. 243234c72144SAxel Dörfler rv = DecrementAddonFlavorInstancesCount(addonID, flavorID); 243354187cc6Sbeveloper if (rv != B_OK) { 243434c72144SAxel Dörfler ERROR("BMediaRosterEx::InstantiateDormantNode: DecrementAddon" 243534c72144SAxel Dörfler "FlavorInstancesCount failed\n"); 243654187cc6Sbeveloper } 24378c6a6096Sbeveloper return B_ERROR; 24388c6a6096Sbeveloper } 24398c6a6096Sbeveloper 244054187cc6Sbeveloper if (creator != -1) { 244134c72144SAxel Dörfler // send a message to the server to assign team "creator" as creator 244234c72144SAxel Dörfler // of node "node->ID()" 244334c72144SAxel Dörfler printf("!!! BMediaRosterEx::InstantiateDormantNode assigning team " 244434c72144SAxel Dörfler "%ld as creator of node %ld\n", creator, node->ID()); 244534c72144SAxel Dörfler 244654187cc6Sbeveloper rv = MediaRosterEx(this)->SetNodeCreator(node->ID(), creator); 244754187cc6Sbeveloper if (rv != B_OK) { 244834c72144SAxel Dörfler ERROR("BMediaRosterEx::InstantiateDormantNode failed to assign " 244934c72144SAxel Dörfler "team %ld as creator of node %ld\n", creator, node->ID()); 245054187cc6Sbeveloper // do not return, this is a minor problem, not a reason to fail 245154187cc6Sbeveloper } 245254187cc6Sbeveloper } 245354187cc6Sbeveloper 245454187cc6Sbeveloper // RegisterNode() does remember the add-on id in the server 245554187cc6Sbeveloper // and UnregisterNode() will call DormantNodeManager::PutAddon() 245654187cc6Sbeveloper // when the node is unregistered. 24578c6a6096Sbeveloper 245834c72144SAxel Dörfler *_node = node->Node(); 2459cf4e2277Sbeveloper 246034c72144SAxel Dörfler TRACE("BMediaRosterEx::InstantiateDormantNode: addon-id %ld, flavor_id " 246134c72144SAxel Dörfler "%ld instanciated as node %ld, port %ld in team %ld\n", addonID, 246234c72144SAxel Dörfler flavorID, _node->node, _node->port, team); 2463cf4e2277Sbeveloper 246416b7eea4Sbeveloper return B_OK; 246516b7eea4Sbeveloper } 246652a38012Sejakowatz 246752a38012Sejakowatz 246852a38012Sejakowatz status_t 246934c72144SAxel Dörfler BMediaRoster::InstantiateDormantNode(const dormant_node_info& info, 247034c72144SAxel Dörfler media_node* _node, uint32 flags) 24718b04ffc1Sbeveloper { 24728b04ffc1Sbeveloper CALLED(); 247334c72144SAxel Dörfler if (_node == NULL) 24748b04ffc1Sbeveloper return B_BAD_VALUE; 247534c72144SAxel Dörfler if (info.addon <= B_OK) { 247634c72144SAxel Dörfler ERROR("BMediaRoster::InstantiateDormantNode error: addon-id %ld " 247734c72144SAxel Dörfler "invalid.\n", info.addon); 24788b04ffc1Sbeveloper return B_BAD_VALUE; 24798b04ffc1Sbeveloper } 24808b04ffc1Sbeveloper 248134c72144SAxel Dörfler printf("BMediaRoster::InstantiateDormantNode: addon-id %ld, flavor_id " 248234c72144SAxel Dörfler "%ld, flags 0x%lX\n", info.addon, info.flavor_id, flags); 24838b04ffc1Sbeveloper 24848b04ffc1Sbeveloper // Get flavor_info from the server 248534c72144SAxel Dörfler // TODO: this is a little overhead, as we get the full blown 248634c72144SAxel Dörfler // dormant_flavor_info, 248734c72144SAxel Dörfler // TODO: but only need the flags. 248834c72144SAxel Dörfler dormant_flavor_info flavorInfo; 24898b04ffc1Sbeveloper status_t rv; 249034c72144SAxel Dörfler rv = MediaRosterEx(this)->GetDormantFlavorInfo(info.addon, info.flavor_id, 249134c72144SAxel Dörfler &flavorInfo); 24928b04ffc1Sbeveloper if (rv != B_OK) { 249334c72144SAxel Dörfler ERROR("BMediaRoster::InstantiateDormantNode: failed to get " 249434c72144SAxel Dörfler "dormant_flavor_info for addon-id %ld, flavor-id %ld\n", 249534c72144SAxel Dörfler info.addon, info.flavor_id); 2496626824eaSbeveloper return B_NAME_NOT_FOUND; 24978b04ffc1Sbeveloper } 24988b04ffc1Sbeveloper 249934c72144SAxel Dörfler ASSERT(flavorInfo.internal_id == info.flavor_id); 25008b04ffc1Sbeveloper 25018b04ffc1Sbeveloper #if DEBUG 250234c72144SAxel Dörfler printf("BMediaRoster::InstantiateDormantNode: name \"%s\", info \"%s\", " 250334c72144SAxel Dörfler "flavor_flags 0x%lX, internal_id %ld, possible_count %ld\n", 250434c72144SAxel Dörfler flavorInfo.name, flavorInfo.info, flavorInfo.flavor_flags, 250534c72144SAxel Dörfler flavorInfo.internal_id, flavorInfo.possible_count); 250634c72144SAxel Dörfler 250734c72144SAxel Dörfler if ((flags & B_FLAVOR_IS_LOCAL) != 0) { 250834c72144SAxel Dörfler printf("BMediaRoster::InstantiateDormantNode: caller requested " 250934c72144SAxel Dörfler "B_FLAVOR_IS_LOCAL\n"); 251034c72144SAxel Dörfler } 251134c72144SAxel Dörfler if ((flags & B_FLAVOR_IS_GLOBAL) != 0) { 251234c72144SAxel Dörfler printf("BMediaRoster::InstantiateDormantNode: caller requested " 251334c72144SAxel Dörfler "B_FLAVOR_IS_GLOBAL\n"); 251434c72144SAxel Dörfler } 251534c72144SAxel Dörfler if ((flavorInfo.flavor_flags & B_FLAVOR_IS_LOCAL) != 0) { 251634c72144SAxel Dörfler printf("BMediaRoster::InstantiateDormantNode: node requires " 251734c72144SAxel Dörfler "B_FLAVOR_IS_LOCAL\n"); 251834c72144SAxel Dörfler } 251934c72144SAxel Dörfler if ((flavorInfo.flavor_flags & B_FLAVOR_IS_GLOBAL) != 0) { 252034c72144SAxel Dörfler printf("BMediaRoster::InstantiateDormantNode: node requires " 252134c72144SAxel Dörfler "B_FLAVOR_IS_GLOBAL\n"); 252234c72144SAxel Dörfler } 25238b04ffc1Sbeveloper #endif 25248b04ffc1Sbeveloper 25258b04ffc1Sbeveloper // Make sure that flags demanded by the dormant node and those requested 25268b04ffc1Sbeveloper // by the caller are not incompatible. 252734c72144SAxel Dörfler if ((flavorInfo.flavor_flags & B_FLAVOR_IS_GLOBAL) != 0 252834c72144SAxel Dörfler && (flags & B_FLAVOR_IS_LOCAL) != 0) { 252934c72144SAxel Dörfler ERROR("BMediaRoster::InstantiateDormantNode: requested " 253034c72144SAxel Dörfler "B_FLAVOR_IS_LOCAL, but dormant node has B_FLAVOR_IS_GLOBAL\n"); 2531626824eaSbeveloper return B_NAME_NOT_FOUND; 25328b04ffc1Sbeveloper } 253334c72144SAxel Dörfler if ((flavorInfo.flavor_flags & B_FLAVOR_IS_LOCAL) != 0 253434c72144SAxel Dörfler && (flags & B_FLAVOR_IS_GLOBAL) != 0) { 253534c72144SAxel Dörfler ERROR("BMediaRoster::InstantiateDormantNode: requested " 253634c72144SAxel Dörfler "B_FLAVOR_IS_GLOBAL, but dormant node has B_FLAVOR_IS_LOCAL\n"); 2537626824eaSbeveloper return B_NAME_NOT_FOUND; 25388b04ffc1Sbeveloper } 253954187cc6Sbeveloper 25408b04ffc1Sbeveloper // If either the node, or the caller requested to make the instance global 254134c72144SAxel Dörfler // we will do it by forwarding this request into the media_addon_server, 254234c72144SAxel Dörfler // which in turn will call BMediaRosterEx::InstantiateDormantNode to create 254334c72144SAxel Dörfler // the node there and make it globally available. 254434c72144SAxel Dörfler if ((flavorInfo.flavor_flags & B_FLAVOR_IS_GLOBAL) != 0 254534c72144SAxel Dörfler || (flags & B_FLAVOR_IS_GLOBAL) != 0) { 254634c72144SAxel Dörfler TRACE("BMediaRoster::InstantiateDormantNode: creating global object " 254734c72144SAxel Dörfler "in media_addon_server\n"); 2548cf4e2277Sbeveloper 25498b04ffc1Sbeveloper addonserver_instantiate_dormant_node_request request; 25508b04ffc1Sbeveloper addonserver_instantiate_dormant_node_reply reply; 255134c72144SAxel Dörfler request.addonid = info.addon; 255234c72144SAxel Dörfler request.flavorid = info.flavor_id; 255334c72144SAxel Dörfler request.creator_team = team; 255434c72144SAxel Dörfler // creator team is allowed to also release global nodes 255534c72144SAxel Dörfler rv = QueryAddonServer(ADDONSERVER_INSTANTIATE_DORMANT_NODE, &request, 255634c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 255734c72144SAxel Dörfler if (rv == B_OK) 255834c72144SAxel Dörfler *_node = reply.node; 25598b04ffc1Sbeveloper } else { 256054187cc6Sbeveloper // creator team = -1, as this is a local node 256134c72144SAxel Dörfler rv = MediaRosterEx(this)->InstantiateDormantNode(info.addon, 256234c72144SAxel Dörfler info.flavor_id, -1, _node); 25638b04ffc1Sbeveloper } 2564626824eaSbeveloper if (rv != B_OK) { 256534c72144SAxel Dörfler *_node = media_node::null; 2566626824eaSbeveloper return B_NAME_NOT_FOUND; 2567626824eaSbeveloper } 2568626824eaSbeveloper return B_OK; 25698b04ffc1Sbeveloper } 25708b04ffc1Sbeveloper 25718b04ffc1Sbeveloper 25728b04ffc1Sbeveloper status_t 257334c72144SAxel Dörfler BMediaRoster::InstantiateDormantNode(const dormant_node_info& info, 257434c72144SAxel Dörfler media_node* _node) 25758b04ffc1Sbeveloper { 257634c72144SAxel Dörfler return InstantiateDormantNode(info, _node, 0); 25778b04ffc1Sbeveloper } 25788b04ffc1Sbeveloper 25798b04ffc1Sbeveloper 25808b04ffc1Sbeveloper status_t 258152a38012Sejakowatz BMediaRoster::GetDormantNodeFor(const media_node& node, 258234c72144SAxel Dörfler dormant_node_info* _info) 258352a38012Sejakowatz { 258485dfab2bSbeveloper CALLED(); 258534c72144SAxel Dörfler if (_info == NULL) 258685dfab2bSbeveloper return B_BAD_VALUE; 258740f36b03Sbeveloper if (IS_INVALID_NODE(node)) 258885dfab2bSbeveloper return B_MEDIA_BAD_NODE; 258952a38012Sejakowatz 259085dfab2bSbeveloper server_get_dormant_node_for_request request; 259185dfab2bSbeveloper server_get_dormant_node_for_reply reply; 259285dfab2bSbeveloper status_t rv; 259385dfab2bSbeveloper 259485dfab2bSbeveloper request.node = node; 259585dfab2bSbeveloper 259634c72144SAxel Dörfler rv = QueryServer(SERVER_GET_DORMANT_NODE_FOR, &request, sizeof(request), 259734c72144SAxel Dörfler &reply, sizeof(reply)); 259885dfab2bSbeveloper if (rv != B_OK) 259985dfab2bSbeveloper return rv; 260085dfab2bSbeveloper 260134c72144SAxel Dörfler *_info = reply.node_info; 260285dfab2bSbeveloper return B_OK; 260352a38012Sejakowatz } 260452a38012Sejakowatz 260534c72144SAxel Dörfler 260652a38012Sejakowatz status_t 260734c72144SAxel Dörfler BMediaRosterEx::GetDormantFlavorInfo(media_addon_id addonID, int32 flavorID, 260834c72144SAxel Dörfler dormant_flavor_info* _flavor) 260952a38012Sejakowatz { 261052a38012Sejakowatz CALLED(); 261134c72144SAxel Dörfler if (_flavor == NULL) 26129bedd42cSbeveloper return B_BAD_VALUE; 261352a38012Sejakowatz 261452a38012Sejakowatz xfer_server_get_dormant_flavor_info msg; 261552a38012Sejakowatz xfer_server_get_dormant_flavor_info_reply *reply; 261652a38012Sejakowatz port_id port; 261752a38012Sejakowatz status_t rv; 261852a38012Sejakowatz int32 code; 261952a38012Sejakowatz 26204295907bSbeveloper port = find_port(MEDIA_SERVER_PORT_NAME); 262134c72144SAxel Dörfler if (port < B_OK) 262252a38012Sejakowatz return B_ERROR; 262352a38012Sejakowatz 262452a38012Sejakowatz reply = (xfer_server_get_dormant_flavor_info_reply*)malloc(16000); 262534c72144SAxel Dörfler if (reply == NULL) 262634c72144SAxel Dörfler return B_NO_MEMORY; 262752a38012Sejakowatz 262834c72144SAxel Dörfler msg.addon = addonID; 262934c72144SAxel Dörfler msg.flavor_id = flavorID; 263052a38012Sejakowatz msg.reply_port = _PortPool->GetPort(); 263152a38012Sejakowatz rv = write_port(port, SERVER_GET_DORMANT_FLAVOR_INFO, &msg, sizeof(msg)); 263252a38012Sejakowatz if (rv != B_OK) { 263352a38012Sejakowatz free(reply); 263452a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 263552a38012Sejakowatz return rv; 263652a38012Sejakowatz } 263752a38012Sejakowatz rv = read_port(msg.reply_port, &code, reply, 16000); 263852a38012Sejakowatz _PortPool->PutPort(msg.reply_port); 263952a38012Sejakowatz 264052a38012Sejakowatz if (rv < B_OK) { 264152a38012Sejakowatz free(reply); 264252a38012Sejakowatz return rv; 264352a38012Sejakowatz } 264452a38012Sejakowatz 264552a38012Sejakowatz if (reply->result == B_OK) 264634c72144SAxel Dörfler rv = _flavor->Unflatten(reply->dfi_type, &reply->dfi, reply->dfi_size); 264752a38012Sejakowatz else 264852a38012Sejakowatz rv = reply->result; 264952a38012Sejakowatz 265052a38012Sejakowatz free(reply); 265152a38012Sejakowatz return rv; 265252a38012Sejakowatz } 265352a38012Sejakowatz 265434c72144SAxel Dörfler 26558b04ffc1Sbeveloper status_t 265634c72144SAxel Dörfler BMediaRoster::GetDormantFlavorInfoFor(const dormant_node_info& dormant, 265734c72144SAxel Dörfler dormant_flavor_info* _flavor) 26588b04ffc1Sbeveloper { 265934c72144SAxel Dörfler return MediaRosterEx(this)->GetDormantFlavorInfo(dormant.addon, 266034c72144SAxel Dörfler dormant.flavor_id, _flavor); 26618b04ffc1Sbeveloper } 266252a38012Sejakowatz 266334c72144SAxel Dörfler 266460f15390Sbeveloper // Reports in outLatency the maximum latency found downstream from 266560f15390Sbeveloper // the specified BBufferProducer, producer, given the current connections. 266652a38012Sejakowatz status_t 266734c72144SAxel Dörfler BMediaRoster::GetLatencyFor(const media_node& producer, bigtime_t* _latency) 266852a38012Sejakowatz { 266960f15390Sbeveloper CALLED(); 267034c72144SAxel Dörfler if (_latency == NULL) 267160f15390Sbeveloper return B_BAD_VALUE; 267234c72144SAxel Dörfler if (IS_INVALID_NODE(producer) 267334c72144SAxel Dörfler || (producer.kind & B_BUFFER_PRODUCER) == 0) 267460f15390Sbeveloper return B_MEDIA_BAD_NODE; 267560f15390Sbeveloper 267660f15390Sbeveloper producer_get_latency_request request; 267760f15390Sbeveloper producer_get_latency_reply reply; 267860f15390Sbeveloper status_t rv; 267960f15390Sbeveloper 268034c72144SAxel Dörfler rv = QueryPort(producer.port, PRODUCER_GET_LATENCY, &request, 268134c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 268260f15390Sbeveloper if (rv != B_OK) 268360f15390Sbeveloper return rv; 268460f15390Sbeveloper 268534c72144SAxel Dörfler *_latency = reply.latency; 268660f15390Sbeveloper 2687ab9afde3SMarcus Overhagen // printf("BMediaRoster::GetLatencyFor producer %ld has maximum latency %Ld\n", producer.node, *out_latency); 2688aac800c2Sbeveloper return B_OK; 268952a38012Sejakowatz } 269052a38012Sejakowatz 269152a38012Sejakowatz 269252a38012Sejakowatz status_t 269352a38012Sejakowatz BMediaRoster::GetInitialLatencyFor(const media_node& producer, 269434c72144SAxel Dörfler bigtime_t* _latency, uint32* _flags) 269552a38012Sejakowatz { 2696b65a0ac5SJérôme Duval CALLED(); 269734c72144SAxel Dörfler if (_latency == NULL) 2698b65a0ac5SJérôme Duval return B_BAD_VALUE; 269934c72144SAxel Dörfler if (IS_INVALID_NODE(producer) 270034c72144SAxel Dörfler || (producer.kind & B_BUFFER_PRODUCER) == 0) 2701b65a0ac5SJérôme Duval return B_MEDIA_BAD_NODE; 2702b65a0ac5SJérôme Duval 2703b65a0ac5SJérôme Duval producer_get_initial_latency_request request; 2704b65a0ac5SJérôme Duval producer_get_initial_latency_reply reply; 2705b65a0ac5SJérôme Duval status_t rv; 2706b65a0ac5SJérôme Duval 270734c72144SAxel Dörfler rv = QueryPort(producer.port, PRODUCER_GET_INITIAL_LATENCY, &request, 270834c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 2709b65a0ac5SJérôme Duval if (rv != B_OK) 2710b65a0ac5SJérôme Duval return rv; 2711b65a0ac5SJérôme Duval 271234c72144SAxel Dörfler *_latency = reply.initial_latency; 271334c72144SAxel Dörfler if (_flags != NULL) 271434c72144SAxel Dörfler *_flags = reply.flags; 2715b65a0ac5SJérôme Duval 271634c72144SAxel Dörfler TRACE("BMediaRoster::GetInitialLatencyFor producer %ld has maximum " 271734c72144SAxel Dörfler "initial latency %Ld\n", producer.node, *_latency); 2718aac800c2Sbeveloper return B_OK; 271952a38012Sejakowatz } 272052a38012Sejakowatz 272152a38012Sejakowatz 272252a38012Sejakowatz status_t 272334c72144SAxel Dörfler BMediaRoster::GetStartLatencyFor(const media_node& timeSource, 272434c72144SAxel Dörfler bigtime_t* _latency) 272552a38012Sejakowatz { 2726fc8b28b6SJérôme Duval CALLED(); 272734c72144SAxel Dörfler if (_latency == NULL) 2728fc8b28b6SJérôme Duval return B_BAD_VALUE; 272934c72144SAxel Dörfler if (IS_INVALID_NODE(timeSource) 273034c72144SAxel Dörfler || (timeSource.kind & B_TIME_SOURCE) == 0) 2731fc8b28b6SJérôme Duval return B_MEDIA_BAD_NODE; 2732fc8b28b6SJérôme Duval 2733fc8b28b6SJérôme Duval timesource_get_start_latency_request request; 2734fc8b28b6SJérôme Duval timesource_get_start_latency_reply reply; 2735fc8b28b6SJérôme Duval status_t rv; 2736fc8b28b6SJérôme Duval 273734c72144SAxel Dörfler rv = QueryPort(timeSource.port, TIMESOURCE_GET_START_LATENCY, &request, 273834c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 2739fc8b28b6SJérôme Duval if (rv != B_OK) 2740fc8b28b6SJérôme Duval return rv; 2741fc8b28b6SJérôme Duval 274234c72144SAxel Dörfler *_latency = reply.start_latency; 2743fc8b28b6SJérôme Duval 274434c72144SAxel Dörfler TRACE("BMediaRoster::GetStartLatencyFor timesource %ld has maximum " 274534c72144SAxel Dörfler "initial latency %Ld\n", timeSource.node, *_latency); 2746aac800c2Sbeveloper return B_OK; 274752a38012Sejakowatz } 274852a38012Sejakowatz 274952a38012Sejakowatz 275052a38012Sejakowatz status_t 275134c72144SAxel Dörfler BMediaRoster::GetFileFormatsFor(const media_node& fileInterface, 275234c72144SAxel Dörfler media_file_format* _formats, int32* _numFormats) 275352a38012Sejakowatz { 275452a38012Sejakowatz UNIMPLEMENTED(); 275552a38012Sejakowatz return B_ERROR; 275652a38012Sejakowatz } 275752a38012Sejakowatz 275852a38012Sejakowatz 275952a38012Sejakowatz status_t 276034c72144SAxel Dörfler BMediaRoster::SetRefFor(const media_node& file_interface, const entry_ref& file, 276134c72144SAxel Dörfler bool createAndTruncate, bigtime_t* _length) 276252a38012Sejakowatz { 27636938364bSMaurice Kalinowski CALLED(); 27646938364bSMaurice Kalinowski 27656938364bSMaurice Kalinowski fileinterface_set_ref_request request; 27666938364bSMaurice Kalinowski fileinterface_set_ref_reply reply; 27676938364bSMaurice Kalinowski status_t rv; 27686938364bSMaurice Kalinowski 27696938364bSMaurice Kalinowski request.device = file.device; 27706938364bSMaurice Kalinowski request.directory = file.directory; 27716938364bSMaurice Kalinowski strcpy(request.name, file.name); 277234c72144SAxel Dörfler request.create = createAndTruncate; 277334c72144SAxel Dörfler if (_length != NULL) 277434c72144SAxel Dörfler request.duration = *_length; 27756938364bSMaurice Kalinowski 277634c72144SAxel Dörfler rv = QueryPort(file_interface.port, FILEINTERFACE_SET_REF, &request, 277734c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 27786938364bSMaurice Kalinowski if (rv != B_OK) 27796938364bSMaurice Kalinowski return rv; 27806938364bSMaurice Kalinowski 278134c72144SAxel Dörfler if (!createAndTruncate && _length) 278234c72144SAxel Dörfler *_length = reply.duration; 27836938364bSMaurice Kalinowski 27846938364bSMaurice Kalinowski return B_OK; 278552a38012Sejakowatz } 278652a38012Sejakowatz 278752a38012Sejakowatz 278852a38012Sejakowatz status_t 278934c72144SAxel Dörfler BMediaRoster::GetRefFor(const media_node& node, entry_ref* _file, 279034c72144SAxel Dörfler BMimeType* mimeType) 279152a38012Sejakowatz { 27926938364bSMaurice Kalinowski CALLED(); 27936938364bSMaurice Kalinowski 279434c72144SAxel Dörfler if (!_file) 27956938364bSMaurice Kalinowski return B_BAD_VALUE; 27966938364bSMaurice Kalinowski 27976938364bSMaurice Kalinowski fileinterface_get_ref_request request; 27986938364bSMaurice Kalinowski fileinterface_get_ref_reply reply; 27996938364bSMaurice Kalinowski status_t rv; 28006938364bSMaurice Kalinowski 280134c72144SAxel Dörfler rv = QueryPort(node.port, FILEINTERFACE_GET_REF, &request, sizeof(request), 280234c72144SAxel Dörfler &reply, sizeof(reply)); 28036938364bSMaurice Kalinowski if (rv != B_OK) 28046938364bSMaurice Kalinowski return rv; 28056938364bSMaurice Kalinowski 280634c72144SAxel Dörfler *_file = entry_ref(reply.device, reply.directory, reply.name); 28076938364bSMaurice Kalinowski 280834c72144SAxel Dörfler if (mimeType) 280934c72144SAxel Dörfler mimeType->SetTo(reply.mimetype); 28106938364bSMaurice Kalinowski 28116938364bSMaurice Kalinowski return B_OK; 281252a38012Sejakowatz } 281352a38012Sejakowatz 281452a38012Sejakowatz 281552a38012Sejakowatz status_t 281652a38012Sejakowatz BMediaRoster::SniffRefFor(const media_node& file_interface, 281734c72144SAxel Dörfler const entry_ref& file, BMimeType* mimeType, float* _capability) 281852a38012Sejakowatz { 28196938364bSMaurice Kalinowski CALLED(); 282034c72144SAxel Dörfler if (mimeType == NULL || _capability == NULL) 28216938364bSMaurice Kalinowski return B_BAD_VALUE; 28226938364bSMaurice Kalinowski 28236938364bSMaurice Kalinowski fileinterface_sniff_ref_request request; 28246938364bSMaurice Kalinowski fileinterface_sniff_ref_reply reply; 28256938364bSMaurice Kalinowski status_t rv; 28266938364bSMaurice Kalinowski 28276938364bSMaurice Kalinowski request.device = file.device; 28286938364bSMaurice Kalinowski request.directory = file.directory; 28296938364bSMaurice Kalinowski strcpy(request.name, file.name); 28306938364bSMaurice Kalinowski 283134c72144SAxel Dörfler rv = QueryPort(file_interface.port, FILEINTERFACE_SNIFF_REF, &request, 283234c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 28336938364bSMaurice Kalinowski if (rv != B_OK) 28346938364bSMaurice Kalinowski return rv; 28356938364bSMaurice Kalinowski 283634c72144SAxel Dörfler mimeType->SetTo(reply.mimetype); 283734c72144SAxel Dörfler *_capability = reply.capability; 28386938364bSMaurice Kalinowski 28396938364bSMaurice Kalinowski return B_OK; 284052a38012Sejakowatz } 284152a38012Sejakowatz 284252a38012Sejakowatz 284334c72144SAxel Dörfler /*! This is the generic "here's a file, now can someone please play it" 284434c72144SAxel Dörfler interface. 284534c72144SAxel Dörfler */ 284652a38012Sejakowatz status_t 284734c72144SAxel Dörfler BMediaRoster::SniffRef(const entry_ref& file, uint64 requireNodeKinds, 284834c72144SAxel Dörfler dormant_node_info* _node, BMimeType* mimeType) 284952a38012Sejakowatz { 285052a38012Sejakowatz UNIMPLEMENTED(); 285152a38012Sejakowatz return B_ERROR; 285252a38012Sejakowatz } 285352a38012Sejakowatz 285452a38012Sejakowatz 285552a38012Sejakowatz status_t 285652a38012Sejakowatz BMediaRoster::GetDormantNodeForType(const BMimeType& type, 285734c72144SAxel Dörfler uint64 requireNodeKinds, dormant_node_info* _node) 285852a38012Sejakowatz { 285952a38012Sejakowatz UNIMPLEMENTED(); 286052a38012Sejakowatz return B_ERROR; 286152a38012Sejakowatz } 286252a38012Sejakowatz 286352a38012Sejakowatz 286452a38012Sejakowatz status_t 286534c72144SAxel Dörfler BMediaRoster::GetReadFileFormatsFor(const dormant_node_info& node, 286634c72144SAxel Dörfler media_file_format* _readFormats, int32 readCount, int32* _readCount) 286752a38012Sejakowatz { 286852a38012Sejakowatz UNIMPLEMENTED(); 286952a38012Sejakowatz return B_ERROR; 287052a38012Sejakowatz } 287152a38012Sejakowatz 287252a38012Sejakowatz 287352a38012Sejakowatz status_t 287434c72144SAxel Dörfler BMediaRoster::GetWriteFileFormatsFor(const dormant_node_info& node, 287534c72144SAxel Dörfler media_file_format* _write_formats, int32 writeCount, int32* _writeCount) 287652a38012Sejakowatz { 287752a38012Sejakowatz UNIMPLEMENTED(); 287852a38012Sejakowatz return B_ERROR; 287952a38012Sejakowatz } 288052a38012Sejakowatz 288152a38012Sejakowatz 288252a38012Sejakowatz status_t 288334c72144SAxel Dörfler BMediaRoster::GetFormatFor(const media_output& output, media_format* _format, 288452a38012Sejakowatz uint32 flags) 288552a38012Sejakowatz { 28869bedd42cSbeveloper CALLED(); 288734c72144SAxel Dörfler if (_format == NULL) 28889bedd42cSbeveloper return B_BAD_VALUE; 28899bedd42cSbeveloper if ((output.node.kind & B_BUFFER_PRODUCER) == 0) 28909bedd42cSbeveloper return B_MEDIA_BAD_NODE; 28919bedd42cSbeveloper if (IS_INVALID_SOURCE(output.source)) 28929bedd42cSbeveloper return B_MEDIA_BAD_SOURCE; 28939bedd42cSbeveloper 28949bedd42cSbeveloper producer_format_suggestion_requested_request request; 28959bedd42cSbeveloper producer_format_suggestion_requested_reply reply; 28969bedd42cSbeveloper status_t rv; 28979bedd42cSbeveloper 28989bedd42cSbeveloper request.type = B_MEDIA_UNKNOWN_TYPE; 289934c72144SAxel Dörfler request.quality = 0; // TODO: what should this be? 29009bedd42cSbeveloper 290134c72144SAxel Dörfler rv = QueryPort(output.source.port, PRODUCER_FORMAT_SUGGESTION_REQUESTED, 290234c72144SAxel Dörfler &request, sizeof(request), &reply, sizeof(reply)); 29039bedd42cSbeveloper if (rv != B_OK) 29049bedd42cSbeveloper return rv; 29059bedd42cSbeveloper 290634c72144SAxel Dörfler *_format = reply.format; 29079bedd42cSbeveloper return B_OK; 290852a38012Sejakowatz } 290952a38012Sejakowatz 291052a38012Sejakowatz 291152a38012Sejakowatz status_t 291234c72144SAxel Dörfler BMediaRoster::GetFormatFor(const media_input& input, media_format* _format, 291352a38012Sejakowatz uint32 flags) 291452a38012Sejakowatz { 29159bedd42cSbeveloper CALLED(); 291634c72144SAxel Dörfler if (_format == NULL) 29179bedd42cSbeveloper return B_BAD_VALUE; 29189bedd42cSbeveloper if ((input.node.kind & B_BUFFER_CONSUMER) == 0) 29199bedd42cSbeveloper return B_MEDIA_BAD_NODE; 29209bedd42cSbeveloper if (IS_INVALID_DESTINATION(input.destination)) 29219bedd42cSbeveloper return B_MEDIA_BAD_DESTINATION; 29229bedd42cSbeveloper 29239bedd42cSbeveloper consumer_accept_format_request request; 29249bedd42cSbeveloper consumer_accept_format_reply reply; 29259bedd42cSbeveloper status_t rv; 29269bedd42cSbeveloper 29279bedd42cSbeveloper request.dest = input.destination; 29289bedd42cSbeveloper memset(&request.format, 0, sizeof(request.format)); // wildcard 29299bedd42cSbeveloper 293034c72144SAxel Dörfler rv = QueryPort(input.destination.port, CONSUMER_ACCEPT_FORMAT, &request, 293134c72144SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 29329bedd42cSbeveloper if (rv != B_OK) 29339bedd42cSbeveloper return rv; 29349bedd42cSbeveloper 293534c72144SAxel Dörfler *_format = reply.format; 29369bedd42cSbeveloper return B_OK; 293752a38012Sejakowatz } 293852a38012Sejakowatz 293952a38012Sejakowatz 294052a38012Sejakowatz status_t 294134c72144SAxel Dörfler BMediaRoster::GetFormatFor(const media_node& node, media_format* _format, 294252a38012Sejakowatz float quality) 294352a38012Sejakowatz { 294452a38012Sejakowatz UNIMPLEMENTED(); 294534c72144SAxel Dörfler if (_format == NULL) 29469bedd42cSbeveloper return B_BAD_VALUE; 29479bedd42cSbeveloper if (IS_INVALID_NODE(node)) 29489bedd42cSbeveloper return B_MEDIA_BAD_NODE; 29499bedd42cSbeveloper if ((node.kind & (B_BUFFER_CONSUMER | B_BUFFER_PRODUCER)) == 0) 29509bedd42cSbeveloper return B_MEDIA_BAD_NODE; 29519bedd42cSbeveloper 295252a38012Sejakowatz return B_ERROR; 295352a38012Sejakowatz } 295452a38012Sejakowatz 295552a38012Sejakowatz 295652a38012Sejakowatz ssize_t 295752a38012Sejakowatz BMediaRoster::GetNodeAttributesFor(const media_node& node, 295834c72144SAxel Dörfler media_node_attribute* _array, size_t maxCount) 295952a38012Sejakowatz { 296052a38012Sejakowatz UNIMPLEMENTED(); 296152a38012Sejakowatz return B_ERROR; 296252a38012Sejakowatz } 296352a38012Sejakowatz 296452a38012Sejakowatz 296552a38012Sejakowatz media_node_id 296634c72144SAxel Dörfler BMediaRoster::NodeIDFor(port_id port) 296752a38012Sejakowatz { 29689e9417d2Sbeveloper CALLED(); 29699e9417d2Sbeveloper 29709e9417d2Sbeveloper server_node_id_for_request request; 29719e9417d2Sbeveloper server_node_id_for_reply reply; 29729e9417d2Sbeveloper status_t rv; 29739e9417d2Sbeveloper 297434c72144SAxel Dörfler request.port = port; 29759e9417d2Sbeveloper 297634c72144SAxel Dörfler rv = QueryServer(SERVER_NODE_ID_FOR, &request, sizeof(request), &reply, 297734c72144SAxel Dörfler sizeof(reply)); 29789e9417d2Sbeveloper if (rv != B_OK) { 29795ac4fbd7Sbeveloper ERROR("BMediaRoster::NodeIDFor: failed (error %#lx)\n", rv); 29809e9417d2Sbeveloper return -1; 29819e9417d2Sbeveloper } 29829e9417d2Sbeveloper 29839e9417d2Sbeveloper return reply.nodeid; 298452a38012Sejakowatz } 298552a38012Sejakowatz 298652a38012Sejakowatz 298752a38012Sejakowatz status_t 298834c72144SAxel Dörfler BMediaRoster::GetInstancesFor(media_addon_id addon, int32 flavor, 298934c72144SAxel Dörfler media_node_id* _id, int32* _count) 299052a38012Sejakowatz { 299185dfab2bSbeveloper CALLED(); 299234c72144SAxel Dörfler if (_id == NULL) 299385dfab2bSbeveloper return B_BAD_VALUE; 299434c72144SAxel Dörfler if (_count && *_count <= 0) 299585dfab2bSbeveloper return B_BAD_VALUE; 299685dfab2bSbeveloper 299785dfab2bSbeveloper server_get_instances_for_request request; 299885dfab2bSbeveloper server_get_instances_for_reply reply; 299985dfab2bSbeveloper status_t rv; 300085dfab2bSbeveloper 300134c72144SAxel Dörfler request.maxcount = (_count ? *_count : 1); 300285dfab2bSbeveloper request.addon_id = addon; 300385dfab2bSbeveloper request.addon_flavor_id = flavor; 300485dfab2bSbeveloper 300534c72144SAxel Dörfler rv = QueryServer(SERVER_GET_INSTANCES_FOR, &request, sizeof(request), 300634c72144SAxel Dörfler &reply, sizeof(reply)); 300785dfab2bSbeveloper if (rv != B_OK) { 30085ac4fbd7Sbeveloper ERROR("BMediaRoster::GetLiveNodes failed\n"); 300985dfab2bSbeveloper return rv; 301052a38012Sejakowatz } 301152a38012Sejakowatz 301234c72144SAxel Dörfler if (_count) 301334c72144SAxel Dörfler *_count = reply.count; 301485dfab2bSbeveloper if (reply.count > 0) 301534c72144SAxel Dörfler memcpy(_id, reply.node_id, sizeof(media_node_id) * reply.count); 301685dfab2bSbeveloper 301785dfab2bSbeveloper return B_OK; 301885dfab2bSbeveloper } 301952a38012Sejakowatz 302052a38012Sejakowatz 302152a38012Sejakowatz status_t 302234c72144SAxel Dörfler BMediaRoster::SetRealtimeFlags(uint32 enabled) 302352a38012Sejakowatz { 302452a38012Sejakowatz UNIMPLEMENTED(); 302552a38012Sejakowatz return B_ERROR; 302652a38012Sejakowatz } 302752a38012Sejakowatz 302852a38012Sejakowatz 302952a38012Sejakowatz status_t 303034c72144SAxel Dörfler BMediaRoster::GetRealtimeFlags(uint32* _enabled) 303152a38012Sejakowatz { 303252a38012Sejakowatz UNIMPLEMENTED(); 303352a38012Sejakowatz return B_ERROR; 303452a38012Sejakowatz } 303552a38012Sejakowatz 303652a38012Sejakowatz 303752a38012Sejakowatz ssize_t 303834c72144SAxel Dörfler BMediaRoster::AudioBufferSizeFor(int32 channelCount, uint32 sampleFormat, 303934c72144SAxel Dörfler float frameRate, bus_type busKind) 304052a38012Sejakowatz { 304134c72144SAxel Dörfler bigtime_t bufferDuration; 304234c72144SAxel Dörfler ssize_t bufferSize; 3043df6c2e83Sbeveloper 3044df6c2e83Sbeveloper system_info info; 3045df6c2e83Sbeveloper get_system_info(&info); 3046df6c2e83Sbeveloper 304734c72144SAxel Dörfler if (info.cpu_clock_speed > 2000000000) // 2 GHz 304834c72144SAxel Dörfler bufferDuration = 2500; 3049df6c2e83Sbeveloper else if (info.cpu_clock_speed > 1000000000) 305034c72144SAxel Dörfler bufferDuration = 5000; 3051df6c2e83Sbeveloper else if (info.cpu_clock_speed > 600000000) 305234c72144SAxel Dörfler bufferDuration = 10000; 3053df6c2e83Sbeveloper else if (info.cpu_clock_speed > 200000000) 305434c72144SAxel Dörfler bufferDuration = 20000; 3055df6c2e83Sbeveloper else if (info.cpu_clock_speed > 100000000) 305634c72144SAxel Dörfler bufferDuration = 30000; 3057df6c2e83Sbeveloper else 305834c72144SAxel Dörfler bufferDuration = 50000; 3059df6c2e83Sbeveloper 306034c72144SAxel Dörfler if ((busKind == B_ISA_BUS || busKind == B_PCMCIA_BUS) 306134c72144SAxel Dörfler && bufferDuration < 25000) 306234c72144SAxel Dörfler bufferDuration = 25000; 3063df6c2e83Sbeveloper 306434c72144SAxel Dörfler bufferSize = (sampleFormat & 0xf) * channelCount 306534c72144SAxel Dörfler * (ssize_t)((frameRate * bufferDuration) / 1000000.0); 3066df6c2e83Sbeveloper 306734c72144SAxel Dörfler printf("Suggested buffer duration %Ld, size %ld\n", bufferDuration, 306834c72144SAxel Dörfler bufferSize); 3069df6c2e83Sbeveloper 307034c72144SAxel Dörfler return bufferSize; 307152a38012Sejakowatz } 307252a38012Sejakowatz 307352a38012Sejakowatz 307434c72144SAxel Dörfler /*! Use MediaFlags to inquire about specific features of the Media Kit. 307534c72144SAxel Dörfler Returns < 0 for "not present", positive size for output data size. 307634c72144SAxel Dörfler 0 means that the capability is present, but no data about it. 307734c72144SAxel Dörfler */ 307852a38012Sejakowatz /*static*/ ssize_t 307934c72144SAxel Dörfler BMediaRoster::MediaFlags(media_flags cap, void* buffer, size_t maxSize) 308052a38012Sejakowatz { 308152a38012Sejakowatz UNIMPLEMENTED(); 308252a38012Sejakowatz return 0; 308352a38012Sejakowatz } 308452a38012Sejakowatz 308552a38012Sejakowatz 308634c72144SAxel Dörfler // #pragma mark - BLooper overrides 308734c72144SAxel Dörfler 308834c72144SAxel Dörfler 308934c72144SAxel Dörfler void 309052a38012Sejakowatz BMediaRoster::MessageReceived(BMessage* message) 309152a38012Sejakowatz { 3092cf4e2277Sbeveloper switch (message->what) { 3093cf4e2277Sbeveloper case 'PING': 3094cf4e2277Sbeveloper { 30956396865dSbeveloper // media_server plays ping-pong with the BMediaRosters 30966396865dSbeveloper // to detect dead teams. Normal communication uses ports. 30976396865dSbeveloper static BMessage pong('PONG'); 30986396865dSbeveloper message->SendReply(&pong, static_cast<BHandler *>(NULL), 2000000); 30996396865dSbeveloper return; 31006396865dSbeveloper } 31016396865dSbeveloper 3102cf4e2277Sbeveloper case NODE_FINAL_RELEASE: 3103cf4e2277Sbeveloper { 3104cf4e2277Sbeveloper // this function is called by a BMediaNode to delete 3105cf4e2277Sbeveloper // itself, as this needs to be done from another thread 3106cf4e2277Sbeveloper // context, it is done here. 310734c72144SAxel Dörfler // TODO: If a node is released using BMediaRoster::ReleaseNode() 310834c72144SAxel Dörfler // TODO: instead of using BMediaNode::Release() / BMediaNode::Acquire() 310934c72144SAxel Dörfler // TODO: fRefCount of the BMediaNode will not be correct. 3110cf4e2277Sbeveloper 3111cf4e2277Sbeveloper BMediaNode *node; 3112cf4e2277Sbeveloper message->FindPointer("node", reinterpret_cast<void **>(&node)); 3113cf4e2277Sbeveloper 311454187cc6Sbeveloper TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE saving node %ld configuration\n", node->ID()); 311554187cc6Sbeveloper MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(node); 3116cf4e2277Sbeveloper 311754187cc6Sbeveloper TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE releasing node %ld\n", node->ID()); 3118cf4e2277Sbeveloper node->DeleteHook(node); // we don't call Release(), see above! 3119cf4e2277Sbeveloper return; 3120cf4e2277Sbeveloper } 3121cf4e2277Sbeveloper } 31226396865dSbeveloper printf("BMediaRoster::MessageReceived: unknown message!\n"); 31236396865dSbeveloper message->PrintToStream(); 312452a38012Sejakowatz } 312552a38012Sejakowatz 312634c72144SAxel Dörfler 312734c72144SAxel Dörfler bool 312852a38012Sejakowatz BMediaRoster::QuitRequested() 312952a38012Sejakowatz { 313052a38012Sejakowatz UNIMPLEMENTED(); 313152a38012Sejakowatz return true; 313252a38012Sejakowatz } 313352a38012Sejakowatz 313434c72144SAxel Dörfler 313534c72144SAxel Dörfler BHandler* 313634c72144SAxel Dörfler BMediaRoster::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier, 313734c72144SAxel Dörfler int32 form, const char* property) 313852a38012Sejakowatz { 3139286a3c91SJérôme Duval return BLooper::ResolveSpecifier(msg, index, specifier, form, property); 314052a38012Sejakowatz } 314152a38012Sejakowatz 314252a38012Sejakowatz 314334c72144SAxel Dörfler status_t 314452a38012Sejakowatz BMediaRoster::GetSupportedSuites(BMessage* data) 314552a38012Sejakowatz { 3146286a3c91SJérôme Duval return BLooper::GetSupportedSuites(data); 314752a38012Sejakowatz } 314852a38012Sejakowatz 314952a38012Sejakowatz 315052a38012Sejakowatz BMediaRoster::~BMediaRoster() 315152a38012Sejakowatz { 315252a38012Sejakowatz CALLED(); 31536396865dSbeveloper 31546396865dSbeveloper // unregister this application with the media server 31556396865dSbeveloper server_unregister_app_request request; 31566396865dSbeveloper server_unregister_app_reply reply; 31576396865dSbeveloper request.team = team; 315834c72144SAxel Dörfler QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply, 315934c72144SAxel Dörfler sizeof(reply)); 31608b940bb4SStephan Aßmus 31618b940bb4SStephan Aßmus // Unset the global instance pointer, the destructor is also called 31628b940bb4SStephan Aßmus // if a client app calls Lock(); and Quit(); directly. 31639def3bf7SStephan Aßmus sDefaultInstance = NULL; 316452a38012Sejakowatz } 316552a38012Sejakowatz 316652a38012Sejakowatz 316734c72144SAxel Dörfler // #pragma mark - private BMediaRoster 316834c72144SAxel Dörfler 316952a38012Sejakowatz 317052a38012Sejakowatz // deprecated call 317152a38012Sejakowatz status_t 317252a38012Sejakowatz BMediaRoster::SetOutputBuffersFor(const media_source& output, 317334c72144SAxel Dörfler BBufferGroup* group, bool willReclaim) 317452a38012Sejakowatz { 317552a38012Sejakowatz UNIMPLEMENTED(); 31769e9417d2Sbeveloper debugger("BMediaRoster::SetOutputBuffersFor missing\n"); 317752a38012Sejakowatz return B_ERROR; 317852a38012Sejakowatz } 317952a38012Sejakowatz 318052a38012Sejakowatz 318134c72144SAxel Dörfler /* FBC reserved virtuals */ 318252a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_0(void *) { return B_ERROR; } 318352a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_1(void *) { return B_ERROR; } 318452a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_2(void *) { return B_ERROR; } 318552a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_3(void *) { return B_ERROR; } 318652a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_4(void *) { return B_ERROR; } 318752a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_5(void *) { return B_ERROR; } 318852a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_6(void *) { return B_ERROR; } 318952a38012Sejakowatz status_t BMediaRoster::_Reserved_MediaRoster_7(void *) { return B_ERROR; } 319052a38012Sejakowatz 319152a38012Sejakowatz 319234c72144SAxel Dörfler BMediaRoster::BMediaRoster() 319334c72144SAxel Dörfler : BLooper("_BMediaRoster_", B_URGENT_DISPLAY_PRIORITY, 319434c72144SAxel Dörfler B_LOOPER_PORT_DEFAULT_CAPACITY) 319552a38012Sejakowatz { 319652a38012Sejakowatz CALLED(); 31976396865dSbeveloper 31986396865dSbeveloper // start the looper 31996396865dSbeveloper Run(); 320052a38012Sejakowatz } 320152a38012Sejakowatz 32026396865dSbeveloper 32039def3bf7SStephan Aßmus // TODO: Looks like these can be safely removed: 320452a38012Sejakowatz /*static*/ status_t 320552a38012Sejakowatz BMediaRoster::ParseCommand(BMessage& reply) 320652a38012Sejakowatz { 320752a38012Sejakowatz UNIMPLEMENTED(); 320852a38012Sejakowatz return B_ERROR; 320952a38012Sejakowatz } 321052a38012Sejakowatz 321152a38012Sejakowatz 321252a38012Sejakowatz status_t 321334c72144SAxel Dörfler BMediaRoster::GetDefaultInfo(media_node_id forDefault, BMessage& config) 321452a38012Sejakowatz { 321552a38012Sejakowatz UNIMPLEMENTED(); 321652a38012Sejakowatz return B_ERROR; 321752a38012Sejakowatz } 321852a38012Sejakowatz 321952a38012Sejakowatz 322052a38012Sejakowatz status_t 322134c72144SAxel Dörfler BMediaRoster::SetRunningDefault(media_node_id forDefault, 322252a38012Sejakowatz const media_node& node) 322352a38012Sejakowatz { 322452a38012Sejakowatz UNIMPLEMENTED(); 322552a38012Sejakowatz return B_ERROR; 322652a38012Sejakowatz } 322752a38012Sejakowatz 322852a38012Sejakowatz 32299def3bf7SStephan Aßmus // #pragma mark - static variables 323052a38012Sejakowatz 32319def3bf7SStephan Aßmus 32329def3bf7SStephan Aßmus BMediaRoster* BMediaRoster::sDefaultInstance = NULL; 323352a38012Sejakowatz 3234