1255a01c7Sbeveloper /* 2*332cc6bcSAxel Dörfler * Copyright 2010-2012, Axel Dörfler, axeld@pinc-software.de. 399e658c3SAxel Dörfler * Copyright 2002-2003, Marcus Overhagen, <Marcus@Overhagen.de>. 4b289aaf6SAxel Dörfler * Distributed under the terms of the MIT License. 5255a01c7Sbeveloper */ 6255a01c7Sbeveloper 7b289aaf6SAxel Dörfler 8b289aaf6SAxel Dörfler #include <Buffer.h> 960f15390Sbeveloper #include <BufferConsumer.h> 1052a38012Sejakowatz #include <BufferGroup.h> 11b289aaf6SAxel Dörfler #include <BufferProducer.h> 1252a38012Sejakowatz 13b289aaf6SAxel Dörfler #include "debug.h" 14b289aaf6SAxel Dörfler #include "DataExchange.h" 15b289aaf6SAxel Dörfler #include "MediaMisc.h" 16b289aaf6SAxel Dörfler 17b289aaf6SAxel Dörfler 18b289aaf6SAxel Dörfler // #pragma mark - protected BBufferProducer 19b289aaf6SAxel Dörfler 2052a38012Sejakowatz 2152a38012Sejakowatz BBufferProducer::~BBufferProducer() 2252a38012Sejakowatz { 2352a38012Sejakowatz CALLED(); 2452a38012Sejakowatz } 2552a38012Sejakowatz 26b289aaf6SAxel Dörfler 27b289aaf6SAxel Dörfler // #pragma mark - public BBufferProducer 28b289aaf6SAxel Dörfler 2952a38012Sejakowatz 3052a38012Sejakowatz /*static*/ status_t 31b289aaf6SAxel Dörfler BBufferProducer::ClipDataToRegion(int32 format, int32 size, const void* data, 3252a38012Sejakowatz BRegion* region) 3352a38012Sejakowatz { 3452a38012Sejakowatz CALLED(); 3552a38012Sejakowatz 3652a38012Sejakowatz if (format != B_CLIP_SHORT_RUNS) 3752a38012Sejakowatz return B_MEDIA_BAD_CLIP_FORMAT; 3852a38012Sejakowatz 39b289aaf6SAxel Dörfler return clip_shorts_to_region((const int16*)data, size / sizeof(int16), 40b289aaf6SAxel Dörfler region); 4152a38012Sejakowatz } 4252a38012Sejakowatz 43b289aaf6SAxel Dörfler 4452a38012Sejakowatz media_type 4552a38012Sejakowatz BBufferProducer::ProducerType() 4652a38012Sejakowatz { 4752a38012Sejakowatz CALLED(); 4852a38012Sejakowatz return fProducerType; 4952a38012Sejakowatz } 5052a38012Sejakowatz 5152a38012Sejakowatz 52b289aaf6SAxel Dörfler // #pragma mark - protected BBufferProducer 53b289aaf6SAxel Dörfler 54b289aaf6SAxel Dörfler 55b289aaf6SAxel Dörfler BBufferProducer::BBufferProducer(media_type producer_type) 56b289aaf6SAxel Dörfler : 5752a38012Sejakowatz BMediaNode("called by BBufferProducer"), 5852a38012Sejakowatz fProducerType(producer_type), 5952a38012Sejakowatz fInitialLatency(0), 6060f15390Sbeveloper fInitialFlags(0), 6160f15390Sbeveloper fDelay(0) 6252a38012Sejakowatz { 6352a38012Sejakowatz CALLED(); 6452a38012Sejakowatz 6552a38012Sejakowatz AddNodeKind(B_BUFFER_PRODUCER); 6652a38012Sejakowatz } 6752a38012Sejakowatz 6852a38012Sejakowatz 6952a38012Sejakowatz status_t 70b289aaf6SAxel Dörfler BBufferProducer::VideoClippingChanged(const media_source& source, 71b289aaf6SAxel Dörfler int16 numShorts, int16* clipData, const media_video_display_info& display, 72b289aaf6SAxel Dörfler int32* /*_deprecated_*/) 7352a38012Sejakowatz { 7452a38012Sejakowatz CALLED(); 7552a38012Sejakowatz // may be implemented by derived classes 7652a38012Sejakowatz return B_ERROR; 7752a38012Sejakowatz } 7852a38012Sejakowatz 7952a38012Sejakowatz 8052a38012Sejakowatz status_t 81b289aaf6SAxel Dörfler BBufferProducer::GetLatency(bigtime_t* _latency) 8252a38012Sejakowatz { 8360f15390Sbeveloper CALLED(); 8460f15390Sbeveloper // The default implementation of GetLatency() finds the maximum 8552a38012Sejakowatz // latency of your currently-available outputs by iterating over 8652a38012Sejakowatz // them, and returns that value in outLatency 8752a38012Sejakowatz 8860f15390Sbeveloper int32 cookie; 8960f15390Sbeveloper bigtime_t latency; 9060f15390Sbeveloper media_output output; 9160f15390Sbeveloper media_node_id unused; 9260f15390Sbeveloper 93b289aaf6SAxel Dörfler *_latency = 0; 9460f15390Sbeveloper cookie = 0; 95b289aaf6SAxel Dörfler while (GetNextOutput(&cookie, &output) == B_OK) { 9660f15390Sbeveloper if (output.destination == media_destination::null) 9760f15390Sbeveloper continue; 9860f15390Sbeveloper 99b289aaf6SAxel Dörfler if (output.node.node == fNodeID) { 100b289aaf6SAxel Dörfler // avoid port writes (deadlock) if loopback connection 101b289aaf6SAxel Dörfler if (fConsumerThis == NULL) 10260f15390Sbeveloper fConsumerThis = dynamic_cast<BBufferConsumer*>(this); 103b289aaf6SAxel Dörfler if (fConsumerThis == NULL) 10460f15390Sbeveloper continue; 105b289aaf6SAxel Dörfler 10660f15390Sbeveloper latency = 0; 107b289aaf6SAxel Dörfler if (fConsumerThis->GetLatencyFor(output.destination, &latency, 108b289aaf6SAxel Dörfler &unused) == B_OK && latency > *_latency) { 109b289aaf6SAxel Dörfler *_latency = latency; 110b289aaf6SAxel Dörfler } 111b289aaf6SAxel Dörfler } else if (FindLatencyFor(output.destination, &latency, &unused) 112b289aaf6SAxel Dörfler == B_OK && latency > *_latency) { 113b289aaf6SAxel Dörfler *_latency = latency; 11460f15390Sbeveloper } 11560f15390Sbeveloper } 116*332cc6bcSAxel Dörfler printf("BBufferProducer::GetLatency: node %" B_PRId32 ", name \"%s\" has " 117*332cc6bcSAxel Dörfler "max latency %" B_PRId64 "\n", fNodeID, fName, *_latency); 11860f15390Sbeveloper return B_OK; 11952a38012Sejakowatz } 12052a38012Sejakowatz 12152a38012Sejakowatz 12252a38012Sejakowatz status_t 123b289aaf6SAxel Dörfler BBufferProducer::SetPlayRate(int32 numer, int32 denom) 12452a38012Sejakowatz { 12552a38012Sejakowatz CALLED(); 12652a38012Sejakowatz // may be implemented by derived classes 12752a38012Sejakowatz return B_ERROR; 12852a38012Sejakowatz } 12952a38012Sejakowatz 13052a38012Sejakowatz 13152a38012Sejakowatz status_t 132b289aaf6SAxel Dörfler BBufferProducer::HandleMessage(int32 message, const void* data, size_t size) 13352a38012Sejakowatz { 134b289aaf6SAxel Dörfler PRINT(4, "BBufferProducer::HandleMessage %#lx, node %ld\n", message, 135b289aaf6SAxel Dörfler fNodeID); 136b289aaf6SAxel Dörfler 13752a38012Sejakowatz switch (message) { 13860f15390Sbeveloper case PRODUCER_SET_RUN_MODE_DELAY: 13960f15390Sbeveloper { 140b289aaf6SAxel Dörfler const producer_set_run_mode_delay_command* command 141b289aaf6SAxel Dörfler = static_cast<const producer_set_run_mode_delay_command*>(data); 14260f15390Sbeveloper // when changing this, also change NODE_SET_RUN_MODE 14360f15390Sbeveloper fDelay = command->delay; 14460f15390Sbeveloper fRunMode = command->mode; 1451df08d39Sbeveloper TRACE("PRODUCER_SET_RUN_MODE_DELAY: fDelay now %Ld\n", fDelay); 14660f15390Sbeveloper SetRunMode(fRunMode); 14760f15390Sbeveloper return B_OK; 14860f15390Sbeveloper } 14952a38012Sejakowatz 15052a38012Sejakowatz case PRODUCER_FORMAT_SUGGESTION_REQUESTED: 15152a38012Sejakowatz { 152b289aaf6SAxel Dörfler const producer_format_suggestion_requested_request* request 153b289aaf6SAxel Dörfler = static_cast< 154b289aaf6SAxel Dörfler const producer_format_suggestion_requested_request*>(data); 155dfb2ad61Sbeveloper producer_format_suggestion_requested_reply reply; 156b289aaf6SAxel Dörfler status_t status = FormatSuggestionRequested(request->type, 157b289aaf6SAxel Dörfler request->quality, &reply.format); 158b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 15952a38012Sejakowatz return B_OK; 16052a38012Sejakowatz } 16152a38012Sejakowatz 16252a38012Sejakowatz case PRODUCER_FORMAT_PROPOSAL: 16352a38012Sejakowatz { 164b289aaf6SAxel Dörfler const producer_format_proposal_request* request 165b289aaf6SAxel Dörfler = static_cast<const producer_format_proposal_request*>(data); 1668c6a6096Sbeveloper producer_format_proposal_reply reply; 1678c6a6096Sbeveloper reply.format = request->format; 168b289aaf6SAxel Dörfler status_t status = FormatProposal(request->output, &reply.format); 169b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 17052a38012Sejakowatz return B_OK; 17152a38012Sejakowatz } 17252a38012Sejakowatz 17352a38012Sejakowatz case PRODUCER_PREPARE_TO_CONNECT: 17452a38012Sejakowatz { 175b289aaf6SAxel Dörfler const producer_prepare_to_connect_request* request 176b289aaf6SAxel Dörfler = static_cast<const producer_prepare_to_connect_request*>(data); 1778c6a6096Sbeveloper producer_prepare_to_connect_reply reply; 1788c6a6096Sbeveloper reply.format = request->format; 1795ac4fbd7Sbeveloper reply.out_source = request->source; 1808c6a6096Sbeveloper memcpy(reply.name, request->name, B_MEDIA_NAME_LENGTH); 181b289aaf6SAxel Dörfler status_t status = PrepareToConnect(request->source, 182b289aaf6SAxel Dörfler request->destination, &reply.format, &reply.out_source, 183b289aaf6SAxel Dörfler reply.name); 184b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 18552a38012Sejakowatz return B_OK; 18652a38012Sejakowatz } 18752a38012Sejakowatz 18852a38012Sejakowatz case PRODUCER_CONNECT: 18952a38012Sejakowatz { 190b289aaf6SAxel Dörfler const producer_connect_request* request 191b289aaf6SAxel Dörfler = static_cast<const producer_connect_request*>(data); 1928c6a6096Sbeveloper producer_connect_reply reply; 1938c6a6096Sbeveloper memcpy(reply.name, request->name, B_MEDIA_NAME_LENGTH); 194b289aaf6SAxel Dörfler Connect(request->error, request->source, request->destination, 195b289aaf6SAxel Dörfler request->format, reply.name); 1968c6a6096Sbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 19752a38012Sejakowatz return B_OK; 19852a38012Sejakowatz } 19952a38012Sejakowatz 20052a38012Sejakowatz case PRODUCER_DISCONNECT: 20152a38012Sejakowatz { 202b289aaf6SAxel Dörfler const producer_disconnect_request* request 203b289aaf6SAxel Dörfler = static_cast<const producer_disconnect_request*>(data); 2049e9417d2Sbeveloper producer_disconnect_reply reply; 2058c6a6096Sbeveloper Disconnect(request->source, request->destination); 2069e9417d2Sbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 20752a38012Sejakowatz return B_OK; 20852a38012Sejakowatz } 20952a38012Sejakowatz 21052a38012Sejakowatz case PRODUCER_GET_INITIAL_LATENCY: 21152a38012Sejakowatz { 212b289aaf6SAxel Dörfler const producer_get_initial_latency_request* request 213b289aaf6SAxel Dörfler = static_cast< 214b289aaf6SAxel Dörfler const producer_get_initial_latency_request*>(data); 215dfb2ad61Sbeveloper producer_get_initial_latency_reply reply; 21652a38012Sejakowatz reply.initial_latency = fInitialLatency; 21752a38012Sejakowatz reply.flags = fInitialFlags; 218dfb2ad61Sbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 21952a38012Sejakowatz return B_OK; 22052a38012Sejakowatz } 22152a38012Sejakowatz 22252a38012Sejakowatz case PRODUCER_SET_PLAY_RATE: 22352a38012Sejakowatz { 224b289aaf6SAxel Dörfler const producer_set_play_rate_request* request 225b289aaf6SAxel Dörfler = static_cast<const producer_set_play_rate_request*>(data); 226dfb2ad61Sbeveloper producer_set_play_rate_reply reply; 227b289aaf6SAxel Dörfler status_t status = SetPlayRate(request->numer, request->denom); 228b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 22952a38012Sejakowatz return B_OK; 23052a38012Sejakowatz } 23152a38012Sejakowatz 23252a38012Sejakowatz case PRODUCER_GET_LATENCY: 23352a38012Sejakowatz { 234b289aaf6SAxel Dörfler const producer_get_latency_request* request 235b289aaf6SAxel Dörfler = static_cast<const producer_get_latency_request*>(data); 236dfb2ad61Sbeveloper producer_get_latency_reply reply; 237b289aaf6SAxel Dörfler status_t status = GetLatency(&reply.latency); 238b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 23952a38012Sejakowatz return B_OK; 24052a38012Sejakowatz } 24152a38012Sejakowatz 24252a38012Sejakowatz case PRODUCER_GET_NEXT_OUTPUT: 24352a38012Sejakowatz { 244b289aaf6SAxel Dörfler const producer_get_next_output_request* request 245b289aaf6SAxel Dörfler = static_cast<const producer_get_next_output_request*>(data); 2463620737cSbeveloper producer_get_next_output_reply reply; 2478c6a6096Sbeveloper reply.cookie = request->cookie; 248b289aaf6SAxel Dörfler status_t status = GetNextOutput(&reply.cookie, &reply.output); 249b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 25052a38012Sejakowatz return B_OK; 25152a38012Sejakowatz } 25252a38012Sejakowatz 25352a38012Sejakowatz case PRODUCER_DISPOSE_OUTPUT_COOKIE: 25452a38012Sejakowatz { 255b289aaf6SAxel Dörfler const producer_dispose_output_cookie_request*request 256b289aaf6SAxel Dörfler = static_cast< 257b289aaf6SAxel Dörfler const producer_dispose_output_cookie_request*>(data); 2583620737cSbeveloper producer_dispose_output_cookie_reply reply; 2598c6a6096Sbeveloper DisposeOutputCookie(request->cookie); 2603620737cSbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 26152a38012Sejakowatz return B_OK; 26252a38012Sejakowatz } 26352a38012Sejakowatz 26452a38012Sejakowatz case PRODUCER_SET_BUFFER_GROUP: 26552a38012Sejakowatz { 266b289aaf6SAxel Dörfler const producer_set_buffer_group_command* command 267b289aaf6SAxel Dörfler = static_cast<const producer_set_buffer_group_command*>(data); 268dfb2ad61Sbeveloper node_request_completed_command replycommand; 26952a38012Sejakowatz BBufferGroup *group; 270b289aaf6SAxel Dörfler group = command->buffer_count != 0 271b289aaf6SAxel Dörfler ? new BBufferGroup(command->buffer_count, command->buffers) 272b289aaf6SAxel Dörfler : NULL; 273b289aaf6SAxel Dörfler status_t status = SetBufferGroup(command->source, group); 274dfb2ad61Sbeveloper if (command->destination == media_destination::null) 27552a38012Sejakowatz return B_OK; 276b289aaf6SAxel Dörfler replycommand.info.what 277b289aaf6SAxel Dörfler = media_request_info::B_SET_OUTPUT_BUFFERS_FOR; 278dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 279b289aaf6SAxel Dörfler replycommand.info.status = status; 280*332cc6bcSAxel Dörfler replycommand.info.cookie = group; 281dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 282dfb2ad61Sbeveloper replycommand.info.source = command->source; 283dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 284b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 285b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 28652a38012Sejakowatz return B_OK; 28752a38012Sejakowatz } 28852a38012Sejakowatz 28952a38012Sejakowatz case PRODUCER_FORMAT_CHANGE_REQUESTED: 29052a38012Sejakowatz { 291b289aaf6SAxel Dörfler const producer_format_change_requested_command* command 292b289aaf6SAxel Dörfler = static_cast< 293b289aaf6SAxel Dörfler const producer_format_change_requested_command*>(data); 294dfb2ad61Sbeveloper node_request_completed_command replycommand; 295dfb2ad61Sbeveloper replycommand.info.format = command->format; 296b289aaf6SAxel Dörfler status_t status = FormatChangeRequested(command->source, 297b289aaf6SAxel Dörfler command->destination, &replycommand.info.format, NULL); 298dfb2ad61Sbeveloper if (command->destination == media_destination::null) 29952a38012Sejakowatz return B_OK; 300b289aaf6SAxel Dörfler replycommand.info.what 301b289aaf6SAxel Dörfler = media_request_info::B_REQUEST_FORMAT_CHANGE; 302dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 303b289aaf6SAxel Dörfler replycommand.info.status = status; 304dfb2ad61Sbeveloper //replycommand.info.cookie 305dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 306dfb2ad61Sbeveloper replycommand.info.source = command->source; 307dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 308b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 309b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 31052a38012Sejakowatz return B_OK; 31152a38012Sejakowatz } 31252a38012Sejakowatz 31352a38012Sejakowatz case PRODUCER_VIDEO_CLIPPING_CHANGED: 31452a38012Sejakowatz { 315b289aaf6SAxel Dörfler const producer_video_clipping_changed_command* command 316b289aaf6SAxel Dörfler = static_cast< 317b289aaf6SAxel Dörfler const producer_video_clipping_changed_command*>(data); 318dfb2ad61Sbeveloper node_request_completed_command replycommand; 319b289aaf6SAxel Dörfler status_t status = VideoClippingChanged(command->source, 320b289aaf6SAxel Dörfler command->short_count, (int16 *)command->shorts, 321b289aaf6SAxel Dörfler command->display, NULL); 322dfb2ad61Sbeveloper if (command->destination == media_destination::null) 32352a38012Sejakowatz return B_OK; 324b289aaf6SAxel Dörfler replycommand.info.what 325b289aaf6SAxel Dörfler = media_request_info::B_SET_VIDEO_CLIPPING_FOR; 326dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 327b289aaf6SAxel Dörfler replycommand.info.status = status; 328dfb2ad61Sbeveloper //replycommand.info.cookie 329dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 330dfb2ad61Sbeveloper replycommand.info.source = command->source; 331dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 332dfb2ad61Sbeveloper replycommand.info.format.type = B_MEDIA_RAW_VIDEO; 333dfb2ad61Sbeveloper replycommand.info.format.u.raw_video.display = command->display; 334b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 335b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 33652a38012Sejakowatz return B_OK; 33752a38012Sejakowatz } 33852a38012Sejakowatz 33952a38012Sejakowatz case PRODUCER_ADDITIONAL_BUFFER_REQUESTED: 34052a38012Sejakowatz { 341b289aaf6SAxel Dörfler const producer_additional_buffer_requested_command* command 342b289aaf6SAxel Dörfler = static_cast< 343b289aaf6SAxel Dörfler const producer_additional_buffer_requested_command*>(data); 344b289aaf6SAxel Dörfler AdditionalBufferRequested(command->source, command->prev_buffer, 345b289aaf6SAxel Dörfler command->prev_time, command->has_seek_tag 346b289aaf6SAxel Dörfler ? &command->prev_tag : NULL); 34752a38012Sejakowatz return B_OK; 34852a38012Sejakowatz } 34952a38012Sejakowatz 35052a38012Sejakowatz case PRODUCER_LATENCY_CHANGED: 35152a38012Sejakowatz { 352b289aaf6SAxel Dörfler const producer_latency_changed_command* command 353b289aaf6SAxel Dörfler = static_cast<const producer_latency_changed_command*>(data); 354b289aaf6SAxel Dörfler LatencyChanged(command->source, command->destination, 355b289aaf6SAxel Dörfler command->latency, command->flags); 35652a38012Sejakowatz return B_OK; 35752a38012Sejakowatz } 35852a38012Sejakowatz 35952a38012Sejakowatz case PRODUCER_LATE_NOTICE_RECEIVED: 36052a38012Sejakowatz { 361b289aaf6SAxel Dörfler const producer_late_notice_received_command* command 362b289aaf6SAxel Dörfler = static_cast< 363b289aaf6SAxel Dörfler const producer_late_notice_received_command*>(data); 364b289aaf6SAxel Dörfler LateNoticeReceived(command->source, command->how_much, 365b289aaf6SAxel Dörfler command->performance_time); 36652a38012Sejakowatz return B_OK; 36752a38012Sejakowatz } 36852a38012Sejakowatz 36952a38012Sejakowatz case PRODUCER_ENABLE_OUTPUT: 37052a38012Sejakowatz { 371b289aaf6SAxel Dörfler const producer_enable_output_command* command 372b289aaf6SAxel Dörfler = static_cast<const producer_enable_output_command*>(data); 373dfb2ad61Sbeveloper node_request_completed_command replycommand; 374dfb2ad61Sbeveloper EnableOutput(command->source, command->enabled, NULL); 375dfb2ad61Sbeveloper if (command->destination == media_destination::null) 37652a38012Sejakowatz return B_OK; 377b289aaf6SAxel Dörfler 378dfb2ad61Sbeveloper replycommand.info.what = media_request_info::B_SET_OUTPUT_ENABLED; 379dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 380dfb2ad61Sbeveloper replycommand.info.status = B_OK; 381dfb2ad61Sbeveloper //replycommand.info.cookie 382dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 383dfb2ad61Sbeveloper replycommand.info.source = command->source; 384dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 385dfb2ad61Sbeveloper //replycommand.info.format 386b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 387b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 38852a38012Sejakowatz return B_OK; 38952a38012Sejakowatz } 390b289aaf6SAxel Dörfler } 39152a38012Sejakowatz 39252a38012Sejakowatz return B_ERROR; 39352a38012Sejakowatz } 39452a38012Sejakowatz 39552a38012Sejakowatz 39652a38012Sejakowatz void 39752a38012Sejakowatz BBufferProducer::AdditionalBufferRequested(const media_source& source, 398b289aaf6SAxel Dörfler media_buffer_id previousBuffer, bigtime_t previousTime, 399b289aaf6SAxel Dörfler const media_seek_tag* previousTag) 40052a38012Sejakowatz { 40152a38012Sejakowatz CALLED(); 40252a38012Sejakowatz // may be implemented by derived classes 40352a38012Sejakowatz } 40452a38012Sejakowatz 40552a38012Sejakowatz 40652a38012Sejakowatz void 40752a38012Sejakowatz BBufferProducer::LatencyChanged(const media_source& source, 408b289aaf6SAxel Dörfler const media_destination& destination, bigtime_t newLatency, uint32 flags) 40952a38012Sejakowatz { 41052a38012Sejakowatz CALLED(); 41152a38012Sejakowatz // may be implemented by derived classes 41252a38012Sejakowatz } 41352a38012Sejakowatz 41452a38012Sejakowatz 41552a38012Sejakowatz status_t 416b289aaf6SAxel Dörfler BBufferProducer::SendBuffer(BBuffer* buffer, const media_source& source, 41752a38012Sejakowatz const media_destination& destination) 41852a38012Sejakowatz { 41952a38012Sejakowatz CALLED(); 42052a38012Sejakowatz if (destination == media_destination::null) 42152a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 422b289aaf6SAxel Dörfler if (source == media_source::null) 423b289aaf6SAxel Dörfler return B_MEDIA_BAD_SOURCE; 42452a38012Sejakowatz if (buffer == NULL) 42552a38012Sejakowatz return B_BAD_VALUE; 42652a38012Sejakowatz 427dfb2ad61Sbeveloper consumer_buffer_received_command command; 428dfb2ad61Sbeveloper command.buffer = buffer->ID(); 429b289aaf6SAxel Dörfler command.header = *buffer->Header(); 430b289aaf6SAxel Dörfler command.header.buffer = command.buffer; 431b289aaf6SAxel Dörfler command.header.source_port = source.port; 432b289aaf6SAxel Dörfler command.header.source = source.id; 433dfb2ad61Sbeveloper command.header.destination = destination.id; 4341df08d39Sbeveloper command.header.owner = 0; // XXX fill with "buffer owner info area" 435b289aaf6SAxel Dörfler command.header.start_time += fDelay; 436b289aaf6SAxel Dörfler // time compensation as set by BMediaRoster::SetProducerRunModeDelay() 43752a38012Sejakowatz 438a6d316d8Sbeveloper //printf("BBufferProducer::SendBuffer node %2ld, buffer %2ld, start_time %12Ld with lateness %6Ld\n", ID(), buffer->Header()->buffer, command.header.start_time, TimeSource()->Now() - command.header.start_time); 439a6d316d8Sbeveloper 440b289aaf6SAxel Dörfler return SendToPort(destination.port, CONSUMER_BUFFER_RECEIVED, &command, 441b289aaf6SAxel Dörfler sizeof(command)); 44252a38012Sejakowatz } 44352a38012Sejakowatz 44452a38012Sejakowatz 44552a38012Sejakowatz status_t 44652a38012Sejakowatz BBufferProducer::SendDataStatus(int32 status, 447b289aaf6SAxel Dörfler const media_destination& destination, bigtime_t atTime) 44852a38012Sejakowatz { 44952a38012Sejakowatz CALLED(); 45040f36b03Sbeveloper if (IS_INVALID_DESTINATION(destination)) 45152a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 45252a38012Sejakowatz 453dfb2ad61Sbeveloper consumer_producer_data_status_command command; 454dfb2ad61Sbeveloper command.for_whom = destination; 455dfb2ad61Sbeveloper command.status = status; 456b289aaf6SAxel Dörfler command.at_performance_time = atTime; 45752a38012Sejakowatz 458b289aaf6SAxel Dörfler return SendToPort(destination.port, CONSUMER_PRODUCER_DATA_STATUS, &command, 459b289aaf6SAxel Dörfler sizeof(command)); 46052a38012Sejakowatz } 46152a38012Sejakowatz 46252a38012Sejakowatz 46352a38012Sejakowatz status_t 46452a38012Sejakowatz BBufferProducer::ProposeFormatChange(media_format* format, 465b289aaf6SAxel Dörfler const media_destination& destination) 46652a38012Sejakowatz { 46752a38012Sejakowatz CALLED(); 468b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 46952a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 47052a38012Sejakowatz 4718c6a6096Sbeveloper consumer_accept_format_request request; 4728c6a6096Sbeveloper consumer_accept_format_reply reply; 47352a38012Sejakowatz 474b289aaf6SAxel Dörfler request.dest = destination; 4758c6a6096Sbeveloper request.format = *format; 476b289aaf6SAxel Dörfler status_t status = QueryPort(destination.port, CONSUMER_ACCEPT_FORMAT, 477b289aaf6SAxel Dörfler &request, sizeof(request), &reply, sizeof(reply)); 478b289aaf6SAxel Dörfler if (status != B_OK) 479b289aaf6SAxel Dörfler return status; 48052a38012Sejakowatz 48152a38012Sejakowatz *format = reply.format; 4828c6a6096Sbeveloper return B_OK; 48352a38012Sejakowatz } 48452a38012Sejakowatz 48552a38012Sejakowatz 48652a38012Sejakowatz status_t 487b289aaf6SAxel Dörfler BBufferProducer::ChangeFormat(const media_source& source, 488b289aaf6SAxel Dörfler const media_destination& destination, media_format* format) 48952a38012Sejakowatz { 49052a38012Sejakowatz CALLED(); 491b289aaf6SAxel Dörfler if (IS_INVALID_SOURCE(source)) 49252a38012Sejakowatz return B_MEDIA_BAD_SOURCE; 493b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 49452a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 49552a38012Sejakowatz 496dfb2ad61Sbeveloper consumer_format_changed_request request; 497dfb2ad61Sbeveloper consumer_format_changed_reply reply; 49852a38012Sejakowatz 499b289aaf6SAxel Dörfler request.producer = source; 500b289aaf6SAxel Dörfler request.consumer = destination; 5018c6a6096Sbeveloper request.format = *format; 50252a38012Sejakowatz 503dfb2ad61Sbeveloper // we use a request/reply to make this synchronous 504b289aaf6SAxel Dörfler return QueryPort(destination.port, CONSUMER_FORMAT_CHANGED, &request, 505b289aaf6SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 50652a38012Sejakowatz } 50752a38012Sejakowatz 50852a38012Sejakowatz 50952a38012Sejakowatz status_t 510b289aaf6SAxel Dörfler BBufferProducer::FindLatencyFor(const media_destination& destination, 511b289aaf6SAxel Dörfler bigtime_t* _latency, media_node_id* _timesource) 51252a38012Sejakowatz { 51352a38012Sejakowatz CALLED(); 514b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 51552a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 51652a38012Sejakowatz 517dfb2ad61Sbeveloper consumer_get_latency_for_request request; 518dfb2ad61Sbeveloper consumer_get_latency_for_reply reply; 51952a38012Sejakowatz 520b289aaf6SAxel Dörfler request.for_whom = destination; 52152a38012Sejakowatz 522b289aaf6SAxel Dörfler status_t status = QueryPort(destination.port, CONSUMER_GET_LATENCY_FOR, 523b289aaf6SAxel Dörfler &request, sizeof(request), &reply, sizeof(reply)); 524b289aaf6SAxel Dörfler if (status != B_OK) 525b289aaf6SAxel Dörfler return status; 52652a38012Sejakowatz 527b289aaf6SAxel Dörfler *_latency = reply.latency; 528b289aaf6SAxel Dörfler *_timesource = reply.timesource; 529b289aaf6SAxel Dörfler return B_OK; 53052a38012Sejakowatz } 53152a38012Sejakowatz 53252a38012Sejakowatz 53352a38012Sejakowatz status_t 534b289aaf6SAxel Dörfler BBufferProducer::FindSeekTag(const media_destination& destination, 535b289aaf6SAxel Dörfler bigtime_t targetTime, media_seek_tag* _tag, bigtime_t* _tagged_time, 536b289aaf6SAxel Dörfler uint32* _flags, uint32 flags) 53752a38012Sejakowatz { 53852a38012Sejakowatz CALLED(); 539b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 54052a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 54152a38012Sejakowatz 542dfb2ad61Sbeveloper consumer_seek_tag_requested_request request; 543dfb2ad61Sbeveloper consumer_seek_tag_requested_reply reply; 54452a38012Sejakowatz 545b289aaf6SAxel Dörfler request.destination = destination; 546b289aaf6SAxel Dörfler request.target_time = targetTime; 547b289aaf6SAxel Dörfler request.flags = flags; 54852a38012Sejakowatz 549b289aaf6SAxel Dörfler status_t status = QueryPort(destination.port, CONSUMER_SEEK_TAG_REQUESTED, 550b289aaf6SAxel Dörfler &request, sizeof(request), &reply, sizeof(reply)); 551b289aaf6SAxel Dörfler if (status != B_OK) 552b289aaf6SAxel Dörfler return status; 55352a38012Sejakowatz 554b289aaf6SAxel Dörfler *_tag = reply.seek_tag; 555b289aaf6SAxel Dörfler *_tagged_time = reply.tagged_time; 556b289aaf6SAxel Dörfler *_flags = reply.flags; 557b289aaf6SAxel Dörfler return B_OK; 55852a38012Sejakowatz } 55952a38012Sejakowatz 56052a38012Sejakowatz 56152a38012Sejakowatz void 562b289aaf6SAxel Dörfler BBufferProducer::SetInitialLatency(bigtime_t initialLatency, uint32 flags) 56352a38012Sejakowatz { 564b289aaf6SAxel Dörfler fInitialLatency = initialLatency; 56552a38012Sejakowatz fInitialFlags = flags; 56652a38012Sejakowatz } 56752a38012Sejakowatz 568b289aaf6SAxel Dörfler 569b289aaf6SAxel Dörfler // #pragma mark - private BBufferProducer 570b289aaf6SAxel Dörfler 57152a38012Sejakowatz 57252a38012Sejakowatz /* 57352a38012Sejakowatz private unimplemented 57452a38012Sejakowatz BBufferProducer::BBufferProducer() 57552a38012Sejakowatz BBufferProducer::BBufferProducer(const BBufferProducer &clone) 57652a38012Sejakowatz BBufferProducer & BBufferProducer::operator=(const BBufferProducer &clone) 57752a38012Sejakowatz */ 57852a38012Sejakowatz 57952a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_0(void*) { return B_ERROR; } 58052a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_1(void*) { return B_ERROR; } 58152a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_2(void*) { return B_ERROR; } 58252a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_3(void*) { return B_ERROR; } 58352a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_4(void*) { return B_ERROR; } 58452a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_5(void*) { return B_ERROR; } 58552a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_6(void*) { return B_ERROR; } 58652a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_7(void*) { return B_ERROR; } 58752a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_8(void*) { return B_ERROR; } 58852a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_9(void*) { return B_ERROR; } 58952a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_10(void*) { return B_ERROR; } 59052a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_11(void*) { return B_ERROR; } 59152a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_12(void*) { return B_ERROR; } 59252a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_13(void*) { return B_ERROR; } 59352a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_14(void*) { return B_ERROR; } 59452a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_15(void*) { return B_ERROR; } 59552a38012Sejakowatz 59652a38012Sejakowatz 597b289aaf6SAxel Dörfler //! Deprecated. 59852a38012Sejakowatz status_t 599b289aaf6SAxel Dörfler BBufferProducer::SendBuffer(BBuffer* buffer, 600b289aaf6SAxel Dörfler const media_destination& destination) 601b289aaf6SAxel Dörfler { 602b289aaf6SAxel Dörfler CALLED(); 603b289aaf6SAxel Dörfler 604b289aaf6SAxel Dörfler // Try to find the source - this is the best we can do 605b289aaf6SAxel Dörfler media_output output; 606b289aaf6SAxel Dörfler int32 cookie = 0; 607b289aaf6SAxel Dörfler status_t status = GetNextOutput(&cookie, &output); 608b289aaf6SAxel Dörfler if (status != B_OK) 609b289aaf6SAxel Dörfler return status; 610b289aaf6SAxel Dörfler 611b289aaf6SAxel Dörfler return SendBuffer(buffer, output.source, destination); 612b289aaf6SAxel Dörfler } 613b289aaf6SAxel Dörfler 614b289aaf6SAxel Dörfler 615b289aaf6SAxel Dörfler status_t 616b289aaf6SAxel Dörfler BBufferProducer::clip_shorts_to_region(const int16* data, int count, 61752a38012Sejakowatz BRegion* output) 61852a38012Sejakowatz { 61952a38012Sejakowatz UNIMPLEMENTED(); 62052a38012Sejakowatz return B_ERROR; 62152a38012Sejakowatz } 62252a38012Sejakowatz 62352a38012Sejakowatz 62452a38012Sejakowatz status_t 625b289aaf6SAxel Dörfler BBufferProducer::clip_region_to_shorts(const BRegion* input, int16* data, 626b289aaf6SAxel Dörfler int maxCount, int* _count) 62752a38012Sejakowatz { 62852a38012Sejakowatz UNIMPLEMENTED(); 62952a38012Sejakowatz return B_ERROR; 63052a38012Sejakowatz } 631