1255a01c7Sbeveloper /* 2332cc6bcSAxel 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 } 116332cc6bcSAxel Dörfler printf("BBufferProducer::GetLatency: node %" B_PRId32 ", name \"%s\" has " 117332cc6bcSAxel 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; 273*714446cfSDario Casalinuovo 274*714446cfSDario Casalinuovo if (group == NULL || group->InitCheck() != B_OK) { 275*714446cfSDario Casalinuovo ERROR("BBufferProducer::HandleMessage PRODUCER_SET_BUFFER_GROUP" 276*714446cfSDario Casalinuovo " group InitCheck() failed.\n"); 277*714446cfSDario Casalinuovo delete group; 278*714446cfSDario Casalinuovo return B_ERROR; 279*714446cfSDario Casalinuovo } 280b289aaf6SAxel Dörfler status_t status = SetBufferGroup(command->source, group); 281dfb2ad61Sbeveloper if (command->destination == media_destination::null) 28252a38012Sejakowatz return B_OK; 283b289aaf6SAxel Dörfler replycommand.info.what 284b289aaf6SAxel Dörfler = media_request_info::B_SET_OUTPUT_BUFFERS_FOR; 285dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 286b289aaf6SAxel Dörfler replycommand.info.status = status; 287332cc6bcSAxel Dörfler replycommand.info.cookie = group; 288dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 289dfb2ad61Sbeveloper replycommand.info.source = command->source; 290dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 291b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 292b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 29352a38012Sejakowatz return B_OK; 29452a38012Sejakowatz } 29552a38012Sejakowatz 29652a38012Sejakowatz case PRODUCER_FORMAT_CHANGE_REQUESTED: 29752a38012Sejakowatz { 298b289aaf6SAxel Dörfler const producer_format_change_requested_command* command 299b289aaf6SAxel Dörfler = static_cast< 300b289aaf6SAxel Dörfler const producer_format_change_requested_command*>(data); 301dfb2ad61Sbeveloper node_request_completed_command replycommand; 302dfb2ad61Sbeveloper replycommand.info.format = command->format; 303b289aaf6SAxel Dörfler status_t status = FormatChangeRequested(command->source, 304b289aaf6SAxel Dörfler command->destination, &replycommand.info.format, NULL); 305dfb2ad61Sbeveloper if (command->destination == media_destination::null) 30652a38012Sejakowatz return B_OK; 307b289aaf6SAxel Dörfler replycommand.info.what 308b289aaf6SAxel Dörfler = media_request_info::B_REQUEST_FORMAT_CHANGE; 309dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 310b289aaf6SAxel Dörfler replycommand.info.status = status; 311dfb2ad61Sbeveloper //replycommand.info.cookie 312dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 313dfb2ad61Sbeveloper replycommand.info.source = command->source; 314dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 315b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 316b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 31752a38012Sejakowatz return B_OK; 31852a38012Sejakowatz } 31952a38012Sejakowatz 32052a38012Sejakowatz case PRODUCER_VIDEO_CLIPPING_CHANGED: 32152a38012Sejakowatz { 322b289aaf6SAxel Dörfler const producer_video_clipping_changed_command* command 323b289aaf6SAxel Dörfler = static_cast< 324b289aaf6SAxel Dörfler const producer_video_clipping_changed_command*>(data); 325dfb2ad61Sbeveloper node_request_completed_command replycommand; 326b289aaf6SAxel Dörfler status_t status = VideoClippingChanged(command->source, 327b289aaf6SAxel Dörfler command->short_count, (int16 *)command->shorts, 328b289aaf6SAxel Dörfler command->display, NULL); 329dfb2ad61Sbeveloper if (command->destination == media_destination::null) 33052a38012Sejakowatz return B_OK; 331b289aaf6SAxel Dörfler replycommand.info.what 332b289aaf6SAxel Dörfler = media_request_info::B_SET_VIDEO_CLIPPING_FOR; 333dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 334b289aaf6SAxel Dörfler replycommand.info.status = status; 335dfb2ad61Sbeveloper //replycommand.info.cookie 336dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 337dfb2ad61Sbeveloper replycommand.info.source = command->source; 338dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 339dfb2ad61Sbeveloper replycommand.info.format.type = B_MEDIA_RAW_VIDEO; 340dfb2ad61Sbeveloper replycommand.info.format.u.raw_video.display = command->display; 341b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 342b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 34352a38012Sejakowatz return B_OK; 34452a38012Sejakowatz } 34552a38012Sejakowatz 34652a38012Sejakowatz case PRODUCER_ADDITIONAL_BUFFER_REQUESTED: 34752a38012Sejakowatz { 348b289aaf6SAxel Dörfler const producer_additional_buffer_requested_command* command 349b289aaf6SAxel Dörfler = static_cast< 350b289aaf6SAxel Dörfler const producer_additional_buffer_requested_command*>(data); 351b289aaf6SAxel Dörfler AdditionalBufferRequested(command->source, command->prev_buffer, 352b289aaf6SAxel Dörfler command->prev_time, command->has_seek_tag 353b289aaf6SAxel Dörfler ? &command->prev_tag : NULL); 35452a38012Sejakowatz return B_OK; 35552a38012Sejakowatz } 35652a38012Sejakowatz 35752a38012Sejakowatz case PRODUCER_LATENCY_CHANGED: 35852a38012Sejakowatz { 359b289aaf6SAxel Dörfler const producer_latency_changed_command* command 360b289aaf6SAxel Dörfler = static_cast<const producer_latency_changed_command*>(data); 361b289aaf6SAxel Dörfler LatencyChanged(command->source, command->destination, 362b289aaf6SAxel Dörfler command->latency, command->flags); 36352a38012Sejakowatz return B_OK; 36452a38012Sejakowatz } 36552a38012Sejakowatz 36652a38012Sejakowatz case PRODUCER_LATE_NOTICE_RECEIVED: 36752a38012Sejakowatz { 368b289aaf6SAxel Dörfler const producer_late_notice_received_command* command 369b289aaf6SAxel Dörfler = static_cast< 370b289aaf6SAxel Dörfler const producer_late_notice_received_command*>(data); 371b289aaf6SAxel Dörfler LateNoticeReceived(command->source, command->how_much, 372b289aaf6SAxel Dörfler command->performance_time); 37352a38012Sejakowatz return B_OK; 37452a38012Sejakowatz } 37552a38012Sejakowatz 37652a38012Sejakowatz case PRODUCER_ENABLE_OUTPUT: 37752a38012Sejakowatz { 378b289aaf6SAxel Dörfler const producer_enable_output_command* command 379b289aaf6SAxel Dörfler = static_cast<const producer_enable_output_command*>(data); 380dfb2ad61Sbeveloper node_request_completed_command replycommand; 381dfb2ad61Sbeveloper EnableOutput(command->source, command->enabled, NULL); 382dfb2ad61Sbeveloper if (command->destination == media_destination::null) 38352a38012Sejakowatz return B_OK; 384b289aaf6SAxel Dörfler 385dfb2ad61Sbeveloper replycommand.info.what = media_request_info::B_SET_OUTPUT_ENABLED; 386dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 387dfb2ad61Sbeveloper replycommand.info.status = B_OK; 388dfb2ad61Sbeveloper //replycommand.info.cookie 389dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 390dfb2ad61Sbeveloper replycommand.info.source = command->source; 391dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 392dfb2ad61Sbeveloper //replycommand.info.format 393b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 394b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 39552a38012Sejakowatz return B_OK; 39652a38012Sejakowatz } 397b289aaf6SAxel Dörfler } 39852a38012Sejakowatz 39952a38012Sejakowatz return B_ERROR; 40052a38012Sejakowatz } 40152a38012Sejakowatz 40252a38012Sejakowatz 40352a38012Sejakowatz void 40452a38012Sejakowatz BBufferProducer::AdditionalBufferRequested(const media_source& source, 405b289aaf6SAxel Dörfler media_buffer_id previousBuffer, bigtime_t previousTime, 406b289aaf6SAxel Dörfler const media_seek_tag* previousTag) 40752a38012Sejakowatz { 40852a38012Sejakowatz CALLED(); 40952a38012Sejakowatz // may be implemented by derived classes 41052a38012Sejakowatz } 41152a38012Sejakowatz 41252a38012Sejakowatz 41352a38012Sejakowatz void 41452a38012Sejakowatz BBufferProducer::LatencyChanged(const media_source& source, 415b289aaf6SAxel Dörfler const media_destination& destination, bigtime_t newLatency, uint32 flags) 41652a38012Sejakowatz { 41752a38012Sejakowatz CALLED(); 41852a38012Sejakowatz // may be implemented by derived classes 41952a38012Sejakowatz } 42052a38012Sejakowatz 42152a38012Sejakowatz 42252a38012Sejakowatz status_t 423b289aaf6SAxel Dörfler BBufferProducer::SendBuffer(BBuffer* buffer, const media_source& source, 42452a38012Sejakowatz const media_destination& destination) 42552a38012Sejakowatz { 42652a38012Sejakowatz CALLED(); 42752a38012Sejakowatz if (destination == media_destination::null) 42852a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 429b289aaf6SAxel Dörfler if (source == media_source::null) 430b289aaf6SAxel Dörfler return B_MEDIA_BAD_SOURCE; 43152a38012Sejakowatz if (buffer == NULL) 43252a38012Sejakowatz return B_BAD_VALUE; 43352a38012Sejakowatz 434dfb2ad61Sbeveloper consumer_buffer_received_command command; 435dfb2ad61Sbeveloper command.buffer = buffer->ID(); 436b289aaf6SAxel Dörfler command.header = *buffer->Header(); 437b289aaf6SAxel Dörfler command.header.buffer = command.buffer; 438b289aaf6SAxel Dörfler command.header.source_port = source.port; 439b289aaf6SAxel Dörfler command.header.source = source.id; 440dfb2ad61Sbeveloper command.header.destination = destination.id; 4411df08d39Sbeveloper command.header.owner = 0; // XXX fill with "buffer owner info area" 442b289aaf6SAxel Dörfler command.header.start_time += fDelay; 443b289aaf6SAxel Dörfler // time compensation as set by BMediaRoster::SetProducerRunModeDelay() 44452a38012Sejakowatz 445a6d316d8Sbeveloper //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); 446a6d316d8Sbeveloper 447b289aaf6SAxel Dörfler return SendToPort(destination.port, CONSUMER_BUFFER_RECEIVED, &command, 448b289aaf6SAxel Dörfler sizeof(command)); 44952a38012Sejakowatz } 45052a38012Sejakowatz 45152a38012Sejakowatz 45252a38012Sejakowatz status_t 45352a38012Sejakowatz BBufferProducer::SendDataStatus(int32 status, 454b289aaf6SAxel Dörfler const media_destination& destination, bigtime_t atTime) 45552a38012Sejakowatz { 45652a38012Sejakowatz CALLED(); 45740f36b03Sbeveloper if (IS_INVALID_DESTINATION(destination)) 45852a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 45952a38012Sejakowatz 460dfb2ad61Sbeveloper consumer_producer_data_status_command command; 461dfb2ad61Sbeveloper command.for_whom = destination; 462dfb2ad61Sbeveloper command.status = status; 463b289aaf6SAxel Dörfler command.at_performance_time = atTime; 46452a38012Sejakowatz 465b289aaf6SAxel Dörfler return SendToPort(destination.port, CONSUMER_PRODUCER_DATA_STATUS, &command, 466b289aaf6SAxel Dörfler sizeof(command)); 46752a38012Sejakowatz } 46852a38012Sejakowatz 46952a38012Sejakowatz 47052a38012Sejakowatz status_t 47152a38012Sejakowatz BBufferProducer::ProposeFormatChange(media_format* format, 472b289aaf6SAxel Dörfler const media_destination& destination) 47352a38012Sejakowatz { 47452a38012Sejakowatz CALLED(); 475b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 47652a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 47752a38012Sejakowatz 4788c6a6096Sbeveloper consumer_accept_format_request request; 4798c6a6096Sbeveloper consumer_accept_format_reply reply; 48052a38012Sejakowatz 481b289aaf6SAxel Dörfler request.dest = destination; 4828c6a6096Sbeveloper request.format = *format; 483b289aaf6SAxel Dörfler status_t status = QueryPort(destination.port, CONSUMER_ACCEPT_FORMAT, 484b289aaf6SAxel Dörfler &request, sizeof(request), &reply, sizeof(reply)); 485b289aaf6SAxel Dörfler if (status != B_OK) 486b289aaf6SAxel Dörfler return status; 48752a38012Sejakowatz 48852a38012Sejakowatz *format = reply.format; 4898c6a6096Sbeveloper return B_OK; 49052a38012Sejakowatz } 49152a38012Sejakowatz 49252a38012Sejakowatz 49352a38012Sejakowatz status_t 494b289aaf6SAxel Dörfler BBufferProducer::ChangeFormat(const media_source& source, 495b289aaf6SAxel Dörfler const media_destination& destination, media_format* format) 49652a38012Sejakowatz { 49752a38012Sejakowatz CALLED(); 498b289aaf6SAxel Dörfler if (IS_INVALID_SOURCE(source)) 49952a38012Sejakowatz return B_MEDIA_BAD_SOURCE; 500b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 50152a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 50252a38012Sejakowatz 503dfb2ad61Sbeveloper consumer_format_changed_request request; 504dfb2ad61Sbeveloper consumer_format_changed_reply reply; 50552a38012Sejakowatz 506b289aaf6SAxel Dörfler request.producer = source; 507b289aaf6SAxel Dörfler request.consumer = destination; 5088c6a6096Sbeveloper request.format = *format; 50952a38012Sejakowatz 510dfb2ad61Sbeveloper // we use a request/reply to make this synchronous 511b289aaf6SAxel Dörfler return QueryPort(destination.port, CONSUMER_FORMAT_CHANGED, &request, 512b289aaf6SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 51352a38012Sejakowatz } 51452a38012Sejakowatz 51552a38012Sejakowatz 51652a38012Sejakowatz status_t 517b289aaf6SAxel Dörfler BBufferProducer::FindLatencyFor(const media_destination& destination, 518b289aaf6SAxel Dörfler bigtime_t* _latency, media_node_id* _timesource) 51952a38012Sejakowatz { 52052a38012Sejakowatz CALLED(); 521b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 52252a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 52352a38012Sejakowatz 524dfb2ad61Sbeveloper consumer_get_latency_for_request request; 525dfb2ad61Sbeveloper consumer_get_latency_for_reply reply; 52652a38012Sejakowatz 527b289aaf6SAxel Dörfler request.for_whom = destination; 52852a38012Sejakowatz 529b289aaf6SAxel Dörfler status_t status = QueryPort(destination.port, CONSUMER_GET_LATENCY_FOR, 530b289aaf6SAxel Dörfler &request, sizeof(request), &reply, sizeof(reply)); 531b289aaf6SAxel Dörfler if (status != B_OK) 532b289aaf6SAxel Dörfler return status; 53352a38012Sejakowatz 534b289aaf6SAxel Dörfler *_latency = reply.latency; 535b289aaf6SAxel Dörfler *_timesource = reply.timesource; 536b289aaf6SAxel Dörfler return B_OK; 53752a38012Sejakowatz } 53852a38012Sejakowatz 53952a38012Sejakowatz 54052a38012Sejakowatz status_t 541b289aaf6SAxel Dörfler BBufferProducer::FindSeekTag(const media_destination& destination, 542b289aaf6SAxel Dörfler bigtime_t targetTime, media_seek_tag* _tag, bigtime_t* _tagged_time, 543b289aaf6SAxel Dörfler uint32* _flags, uint32 flags) 54452a38012Sejakowatz { 54552a38012Sejakowatz CALLED(); 546b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 54752a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 54852a38012Sejakowatz 549dfb2ad61Sbeveloper consumer_seek_tag_requested_request request; 550dfb2ad61Sbeveloper consumer_seek_tag_requested_reply reply; 55152a38012Sejakowatz 552b289aaf6SAxel Dörfler request.destination = destination; 553b289aaf6SAxel Dörfler request.target_time = targetTime; 554b289aaf6SAxel Dörfler request.flags = flags; 55552a38012Sejakowatz 556b289aaf6SAxel Dörfler status_t status = QueryPort(destination.port, CONSUMER_SEEK_TAG_REQUESTED, 557b289aaf6SAxel Dörfler &request, sizeof(request), &reply, sizeof(reply)); 558b289aaf6SAxel Dörfler if (status != B_OK) 559b289aaf6SAxel Dörfler return status; 56052a38012Sejakowatz 561b289aaf6SAxel Dörfler *_tag = reply.seek_tag; 562b289aaf6SAxel Dörfler *_tagged_time = reply.tagged_time; 563b289aaf6SAxel Dörfler *_flags = reply.flags; 564b289aaf6SAxel Dörfler return B_OK; 56552a38012Sejakowatz } 56652a38012Sejakowatz 56752a38012Sejakowatz 56852a38012Sejakowatz void 569b289aaf6SAxel Dörfler BBufferProducer::SetInitialLatency(bigtime_t initialLatency, uint32 flags) 57052a38012Sejakowatz { 571b289aaf6SAxel Dörfler fInitialLatency = initialLatency; 57252a38012Sejakowatz fInitialFlags = flags; 57352a38012Sejakowatz } 57452a38012Sejakowatz 575b289aaf6SAxel Dörfler 576b289aaf6SAxel Dörfler // #pragma mark - private BBufferProducer 577b289aaf6SAxel Dörfler 57852a38012Sejakowatz 57952a38012Sejakowatz /* 58052a38012Sejakowatz private unimplemented 58152a38012Sejakowatz BBufferProducer::BBufferProducer() 58252a38012Sejakowatz BBufferProducer::BBufferProducer(const BBufferProducer &clone) 58352a38012Sejakowatz BBufferProducer & BBufferProducer::operator=(const BBufferProducer &clone) 58452a38012Sejakowatz */ 58552a38012Sejakowatz 58652a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_0(void*) { return B_ERROR; } 58752a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_1(void*) { return B_ERROR; } 58852a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_2(void*) { return B_ERROR; } 58952a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_3(void*) { return B_ERROR; } 59052a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_4(void*) { return B_ERROR; } 59152a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_5(void*) { return B_ERROR; } 59252a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_6(void*) { return B_ERROR; } 59352a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_7(void*) { return B_ERROR; } 59452a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_8(void*) { return B_ERROR; } 59552a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_9(void*) { return B_ERROR; } 59652a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_10(void*) { return B_ERROR; } 59752a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_11(void*) { return B_ERROR; } 59852a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_12(void*) { return B_ERROR; } 59952a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_13(void*) { return B_ERROR; } 60052a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_14(void*) { return B_ERROR; } 60152a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_15(void*) { return B_ERROR; } 60252a38012Sejakowatz 60352a38012Sejakowatz 604b289aaf6SAxel Dörfler //! Deprecated. 60552a38012Sejakowatz status_t 606b289aaf6SAxel Dörfler BBufferProducer::SendBuffer(BBuffer* buffer, 607b289aaf6SAxel Dörfler const media_destination& destination) 608b289aaf6SAxel Dörfler { 609b289aaf6SAxel Dörfler CALLED(); 610b289aaf6SAxel Dörfler 611b289aaf6SAxel Dörfler // Try to find the source - this is the best we can do 612b289aaf6SAxel Dörfler media_output output; 613b289aaf6SAxel Dörfler int32 cookie = 0; 614b289aaf6SAxel Dörfler status_t status = GetNextOutput(&cookie, &output); 615b289aaf6SAxel Dörfler if (status != B_OK) 616b289aaf6SAxel Dörfler return status; 617b289aaf6SAxel Dörfler 618b289aaf6SAxel Dörfler return SendBuffer(buffer, output.source, destination); 619b289aaf6SAxel Dörfler } 620b289aaf6SAxel Dörfler 621b289aaf6SAxel Dörfler 622b289aaf6SAxel Dörfler status_t 623b289aaf6SAxel Dörfler BBufferProducer::clip_shorts_to_region(const int16* data, int count, 62452a38012Sejakowatz BRegion* output) 62552a38012Sejakowatz { 62652a38012Sejakowatz UNIMPLEMENTED(); 62752a38012Sejakowatz return B_ERROR; 62852a38012Sejakowatz } 62952a38012Sejakowatz 63052a38012Sejakowatz 63152a38012Sejakowatz status_t 632b289aaf6SAxel Dörfler BBufferProducer::clip_region_to_shorts(const BRegion* input, int16* data, 633b289aaf6SAxel Dörfler int maxCount, int* _count) 63452a38012Sejakowatz { 63552a38012Sejakowatz UNIMPLEMENTED(); 63652a38012Sejakowatz return B_ERROR; 63752a38012Sejakowatz } 638