1255a01c7Sbeveloper /* 2*b289aaf6SAxel Dörfler * Copyright 2002-2010, Haiku. 3*b289aaf6SAxel Dörfler * Distributed under the terms of the MIT License. 4255a01c7Sbeveloper * 5*b289aaf6SAxel Dörfler * Authors: 6*b289aaf6SAxel Dörfler * Marcus Overhagen, <Marcus@Overhagen.de> 7*b289aaf6SAxel Dörfler * Axel Dörfler, axeld@pinc-software.de. 8255a01c7Sbeveloper */ 9255a01c7Sbeveloper 10*b289aaf6SAxel Dörfler 11*b289aaf6SAxel Dörfler #include <Buffer.h> 1260f15390Sbeveloper #include <BufferConsumer.h> 1352a38012Sejakowatz #include <BufferGroup.h> 14*b289aaf6SAxel Dörfler #include <BufferProducer.h> 1552a38012Sejakowatz 16*b289aaf6SAxel Dörfler #include "debug.h" 17*b289aaf6SAxel Dörfler #include "DataExchange.h" 18*b289aaf6SAxel Dörfler #include "MediaMisc.h" 19*b289aaf6SAxel Dörfler 20*b289aaf6SAxel Dörfler 21*b289aaf6SAxel Dörfler // #pragma mark - protected BBufferProducer 22*b289aaf6SAxel Dörfler 2352a38012Sejakowatz 2452a38012Sejakowatz BBufferProducer::~BBufferProducer() 2552a38012Sejakowatz { 2652a38012Sejakowatz CALLED(); 2752a38012Sejakowatz } 2852a38012Sejakowatz 29*b289aaf6SAxel Dörfler 30*b289aaf6SAxel Dörfler // #pragma mark - public BBufferProducer 31*b289aaf6SAxel Dörfler 3252a38012Sejakowatz 3352a38012Sejakowatz /*static*/ status_t 34*b289aaf6SAxel Dörfler BBufferProducer::ClipDataToRegion(int32 format, int32 size, const void* data, 3552a38012Sejakowatz BRegion* region) 3652a38012Sejakowatz { 3752a38012Sejakowatz CALLED(); 3852a38012Sejakowatz 3952a38012Sejakowatz if (format != B_CLIP_SHORT_RUNS) 4052a38012Sejakowatz return B_MEDIA_BAD_CLIP_FORMAT; 4152a38012Sejakowatz 42*b289aaf6SAxel Dörfler return clip_shorts_to_region((const int16*)data, size / sizeof(int16), 43*b289aaf6SAxel Dörfler region); 4452a38012Sejakowatz } 4552a38012Sejakowatz 46*b289aaf6SAxel Dörfler 4752a38012Sejakowatz media_type 4852a38012Sejakowatz BBufferProducer::ProducerType() 4952a38012Sejakowatz { 5052a38012Sejakowatz CALLED(); 5152a38012Sejakowatz return fProducerType; 5252a38012Sejakowatz } 5352a38012Sejakowatz 5452a38012Sejakowatz 55*b289aaf6SAxel Dörfler // #pragma mark - protected BBufferProducer 56*b289aaf6SAxel Dörfler 57*b289aaf6SAxel Dörfler 58*b289aaf6SAxel Dörfler BBufferProducer::BBufferProducer(media_type producer_type) 59*b289aaf6SAxel Dörfler : 6052a38012Sejakowatz BMediaNode("called by BBufferProducer"), 6152a38012Sejakowatz fProducerType(producer_type), 6252a38012Sejakowatz fInitialLatency(0), 6360f15390Sbeveloper fInitialFlags(0), 6460f15390Sbeveloper fDelay(0) 6552a38012Sejakowatz { 6652a38012Sejakowatz CALLED(); 6752a38012Sejakowatz 6852a38012Sejakowatz AddNodeKind(B_BUFFER_PRODUCER); 6952a38012Sejakowatz } 7052a38012Sejakowatz 7152a38012Sejakowatz 7252a38012Sejakowatz status_t 73*b289aaf6SAxel Dörfler BBufferProducer::VideoClippingChanged(const media_source& source, 74*b289aaf6SAxel Dörfler int16 numShorts, int16* clipData, const media_video_display_info& display, 75*b289aaf6SAxel Dörfler int32* /*_deprecated_*/) 7652a38012Sejakowatz { 7752a38012Sejakowatz CALLED(); 7852a38012Sejakowatz // may be implemented by derived classes 7952a38012Sejakowatz return B_ERROR; 8052a38012Sejakowatz } 8152a38012Sejakowatz 8252a38012Sejakowatz 8352a38012Sejakowatz status_t 84*b289aaf6SAxel Dörfler BBufferProducer::GetLatency(bigtime_t* _latency) 8552a38012Sejakowatz { 8660f15390Sbeveloper CALLED(); 8760f15390Sbeveloper // The default implementation of GetLatency() finds the maximum 8852a38012Sejakowatz // latency of your currently-available outputs by iterating over 8952a38012Sejakowatz // them, and returns that value in outLatency 9052a38012Sejakowatz 9160f15390Sbeveloper int32 cookie; 9260f15390Sbeveloper bigtime_t latency; 9360f15390Sbeveloper media_output output; 9460f15390Sbeveloper media_node_id unused; 9560f15390Sbeveloper 96*b289aaf6SAxel Dörfler *_latency = 0; 9760f15390Sbeveloper cookie = 0; 98*b289aaf6SAxel Dörfler while (GetNextOutput(&cookie, &output) == B_OK) { 9960f15390Sbeveloper if (output.destination == media_destination::null) 10060f15390Sbeveloper continue; 10160f15390Sbeveloper 102*b289aaf6SAxel Dörfler if (output.node.node == fNodeID) { 103*b289aaf6SAxel Dörfler // avoid port writes (deadlock) if loopback connection 104*b289aaf6SAxel Dörfler if (fConsumerThis == NULL) 10560f15390Sbeveloper fConsumerThis = dynamic_cast<BBufferConsumer*>(this); 106*b289aaf6SAxel Dörfler if (fConsumerThis == NULL) 10760f15390Sbeveloper continue; 108*b289aaf6SAxel Dörfler 10960f15390Sbeveloper latency = 0; 110*b289aaf6SAxel Dörfler if (fConsumerThis->GetLatencyFor(output.destination, &latency, 111*b289aaf6SAxel Dörfler &unused) == B_OK && latency > *_latency) { 112*b289aaf6SAxel Dörfler *_latency = latency; 113*b289aaf6SAxel Dörfler } 114*b289aaf6SAxel Dörfler } else if (FindLatencyFor(output.destination, &latency, &unused) 115*b289aaf6SAxel Dörfler == B_OK && latency > *_latency) { 116*b289aaf6SAxel Dörfler *_latency = latency; 11760f15390Sbeveloper } 11860f15390Sbeveloper } 119*b289aaf6SAxel Dörfler printf("BBufferProducer::GetLatency: node %ld, name \"%s\" has max latency %Ld\n", fNodeID, fName, *_latency); 12060f15390Sbeveloper return B_OK; 12152a38012Sejakowatz } 12252a38012Sejakowatz 12352a38012Sejakowatz 12452a38012Sejakowatz status_t 125*b289aaf6SAxel Dörfler BBufferProducer::SetPlayRate(int32 numer, int32 denom) 12652a38012Sejakowatz { 12752a38012Sejakowatz CALLED(); 12852a38012Sejakowatz // may be implemented by derived classes 12952a38012Sejakowatz return B_ERROR; 13052a38012Sejakowatz } 13152a38012Sejakowatz 13252a38012Sejakowatz 13352a38012Sejakowatz status_t 134*b289aaf6SAxel Dörfler BBufferProducer::HandleMessage(int32 message, const void* data, size_t size) 13552a38012Sejakowatz { 136*b289aaf6SAxel Dörfler PRINT(4, "BBufferProducer::HandleMessage %#lx, node %ld\n", message, 137*b289aaf6SAxel Dörfler fNodeID); 138*b289aaf6SAxel Dörfler 13952a38012Sejakowatz switch (message) { 14060f15390Sbeveloper case PRODUCER_SET_RUN_MODE_DELAY: 14160f15390Sbeveloper { 142*b289aaf6SAxel Dörfler const producer_set_run_mode_delay_command* command 143*b289aaf6SAxel Dörfler = static_cast<const producer_set_run_mode_delay_command*>(data); 14460f15390Sbeveloper // when changing this, also change NODE_SET_RUN_MODE 14560f15390Sbeveloper fDelay = command->delay; 14660f15390Sbeveloper fRunMode = command->mode; 1471df08d39Sbeveloper TRACE("PRODUCER_SET_RUN_MODE_DELAY: fDelay now %Ld\n", fDelay); 14860f15390Sbeveloper SetRunMode(fRunMode); 14960f15390Sbeveloper return B_OK; 15060f15390Sbeveloper } 15152a38012Sejakowatz 15252a38012Sejakowatz case PRODUCER_FORMAT_SUGGESTION_REQUESTED: 15352a38012Sejakowatz { 154*b289aaf6SAxel Dörfler const producer_format_suggestion_requested_request* request 155*b289aaf6SAxel Dörfler = static_cast< 156*b289aaf6SAxel Dörfler const producer_format_suggestion_requested_request*>(data); 157dfb2ad61Sbeveloper producer_format_suggestion_requested_reply reply; 158*b289aaf6SAxel Dörfler status_t status = FormatSuggestionRequested(request->type, 159*b289aaf6SAxel Dörfler request->quality, &reply.format); 160*b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 16152a38012Sejakowatz return B_OK; 16252a38012Sejakowatz } 16352a38012Sejakowatz 16452a38012Sejakowatz case PRODUCER_FORMAT_PROPOSAL: 16552a38012Sejakowatz { 166*b289aaf6SAxel Dörfler const producer_format_proposal_request* request 167*b289aaf6SAxel Dörfler = static_cast<const producer_format_proposal_request*>(data); 1688c6a6096Sbeveloper producer_format_proposal_reply reply; 1698c6a6096Sbeveloper reply.format = request->format; 170*b289aaf6SAxel Dörfler status_t status = FormatProposal(request->output, &reply.format); 171*b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 17252a38012Sejakowatz return B_OK; 17352a38012Sejakowatz } 17452a38012Sejakowatz 17552a38012Sejakowatz case PRODUCER_PREPARE_TO_CONNECT: 17652a38012Sejakowatz { 177*b289aaf6SAxel Dörfler const producer_prepare_to_connect_request* request 178*b289aaf6SAxel Dörfler = static_cast<const producer_prepare_to_connect_request*>(data); 1798c6a6096Sbeveloper producer_prepare_to_connect_reply reply; 1808c6a6096Sbeveloper reply.format = request->format; 1815ac4fbd7Sbeveloper reply.out_source = request->source; 1828c6a6096Sbeveloper memcpy(reply.name, request->name, B_MEDIA_NAME_LENGTH); 183*b289aaf6SAxel Dörfler status_t status = PrepareToConnect(request->source, 184*b289aaf6SAxel Dörfler request->destination, &reply.format, &reply.out_source, 185*b289aaf6SAxel Dörfler reply.name); 186*b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 18752a38012Sejakowatz return B_OK; 18852a38012Sejakowatz } 18952a38012Sejakowatz 19052a38012Sejakowatz case PRODUCER_CONNECT: 19152a38012Sejakowatz { 192*b289aaf6SAxel Dörfler const producer_connect_request* request 193*b289aaf6SAxel Dörfler = static_cast<const producer_connect_request*>(data); 1948c6a6096Sbeveloper producer_connect_reply reply; 1958c6a6096Sbeveloper memcpy(reply.name, request->name, B_MEDIA_NAME_LENGTH); 196*b289aaf6SAxel Dörfler Connect(request->error, request->source, request->destination, 197*b289aaf6SAxel Dörfler request->format, reply.name); 1988c6a6096Sbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 19952a38012Sejakowatz return B_OK; 20052a38012Sejakowatz } 20152a38012Sejakowatz 20252a38012Sejakowatz case PRODUCER_DISCONNECT: 20352a38012Sejakowatz { 204*b289aaf6SAxel Dörfler const producer_disconnect_request* request 205*b289aaf6SAxel Dörfler = static_cast<const producer_disconnect_request*>(data); 2069e9417d2Sbeveloper producer_disconnect_reply reply; 2078c6a6096Sbeveloper Disconnect(request->source, request->destination); 2089e9417d2Sbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 20952a38012Sejakowatz return B_OK; 21052a38012Sejakowatz } 21152a38012Sejakowatz 21252a38012Sejakowatz case PRODUCER_GET_INITIAL_LATENCY: 21352a38012Sejakowatz { 214*b289aaf6SAxel Dörfler const producer_get_initial_latency_request* request 215*b289aaf6SAxel Dörfler = static_cast< 216*b289aaf6SAxel Dörfler const producer_get_initial_latency_request*>(data); 217dfb2ad61Sbeveloper producer_get_initial_latency_reply reply; 21852a38012Sejakowatz reply.initial_latency = fInitialLatency; 21952a38012Sejakowatz reply.flags = fInitialFlags; 220dfb2ad61Sbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 22152a38012Sejakowatz return B_OK; 22252a38012Sejakowatz } 22352a38012Sejakowatz 22452a38012Sejakowatz case PRODUCER_SET_PLAY_RATE: 22552a38012Sejakowatz { 226*b289aaf6SAxel Dörfler const producer_set_play_rate_request* request 227*b289aaf6SAxel Dörfler = static_cast<const producer_set_play_rate_request*>(data); 228dfb2ad61Sbeveloper producer_set_play_rate_reply reply; 229*b289aaf6SAxel Dörfler status_t status = SetPlayRate(request->numer, request->denom); 230*b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 23152a38012Sejakowatz return B_OK; 23252a38012Sejakowatz } 23352a38012Sejakowatz 23452a38012Sejakowatz case PRODUCER_GET_LATENCY: 23552a38012Sejakowatz { 236*b289aaf6SAxel Dörfler const producer_get_latency_request* request 237*b289aaf6SAxel Dörfler = static_cast<const producer_get_latency_request*>(data); 238dfb2ad61Sbeveloper producer_get_latency_reply reply; 239*b289aaf6SAxel Dörfler status_t status = GetLatency(&reply.latency); 240*b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 24152a38012Sejakowatz return B_OK; 24252a38012Sejakowatz } 24352a38012Sejakowatz 24452a38012Sejakowatz case PRODUCER_GET_NEXT_OUTPUT: 24552a38012Sejakowatz { 246*b289aaf6SAxel Dörfler const producer_get_next_output_request* request 247*b289aaf6SAxel Dörfler = static_cast<const producer_get_next_output_request*>(data); 2483620737cSbeveloper producer_get_next_output_reply reply; 2498c6a6096Sbeveloper reply.cookie = request->cookie; 250*b289aaf6SAxel Dörfler status_t status = GetNextOutput(&reply.cookie, &reply.output); 251*b289aaf6SAxel Dörfler request->SendReply(status, &reply, sizeof(reply)); 25252a38012Sejakowatz return B_OK; 25352a38012Sejakowatz } 25452a38012Sejakowatz 25552a38012Sejakowatz case PRODUCER_DISPOSE_OUTPUT_COOKIE: 25652a38012Sejakowatz { 257*b289aaf6SAxel Dörfler const producer_dispose_output_cookie_request*request 258*b289aaf6SAxel Dörfler = static_cast< 259*b289aaf6SAxel Dörfler const producer_dispose_output_cookie_request*>(data); 2603620737cSbeveloper producer_dispose_output_cookie_reply reply; 2618c6a6096Sbeveloper DisposeOutputCookie(request->cookie); 2623620737cSbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 26352a38012Sejakowatz return B_OK; 26452a38012Sejakowatz } 26552a38012Sejakowatz 26652a38012Sejakowatz case PRODUCER_SET_BUFFER_GROUP: 26752a38012Sejakowatz { 268*b289aaf6SAxel Dörfler const producer_set_buffer_group_command* command 269*b289aaf6SAxel Dörfler = static_cast<const producer_set_buffer_group_command*>(data); 270dfb2ad61Sbeveloper node_request_completed_command replycommand; 27152a38012Sejakowatz BBufferGroup *group; 272*b289aaf6SAxel Dörfler group = command->buffer_count != 0 273*b289aaf6SAxel Dörfler ? new BBufferGroup(command->buffer_count, command->buffers) 274*b289aaf6SAxel Dörfler : NULL; 275*b289aaf6SAxel Dörfler status_t status = SetBufferGroup(command->source, group); 276dfb2ad61Sbeveloper if (command->destination == media_destination::null) 27752a38012Sejakowatz return B_OK; 278*b289aaf6SAxel Dörfler replycommand.info.what 279*b289aaf6SAxel Dörfler = media_request_info::B_SET_OUTPUT_BUFFERS_FOR; 280dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 281*b289aaf6SAxel Dörfler replycommand.info.status = status; 282dfb2ad61Sbeveloper replycommand.info.cookie = (int32)group; 283dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 284dfb2ad61Sbeveloper replycommand.info.source = command->source; 285dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 286*b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 287*b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 28852a38012Sejakowatz return B_OK; 28952a38012Sejakowatz } 29052a38012Sejakowatz 29152a38012Sejakowatz case PRODUCER_FORMAT_CHANGE_REQUESTED: 29252a38012Sejakowatz { 293*b289aaf6SAxel Dörfler const producer_format_change_requested_command* command 294*b289aaf6SAxel Dörfler = static_cast< 295*b289aaf6SAxel Dörfler const producer_format_change_requested_command*>(data); 296dfb2ad61Sbeveloper node_request_completed_command replycommand; 297dfb2ad61Sbeveloper replycommand.info.format = command->format; 298*b289aaf6SAxel Dörfler status_t status = FormatChangeRequested(command->source, 299*b289aaf6SAxel Dörfler command->destination, &replycommand.info.format, NULL); 300dfb2ad61Sbeveloper if (command->destination == media_destination::null) 30152a38012Sejakowatz return B_OK; 302*b289aaf6SAxel Dörfler replycommand.info.what 303*b289aaf6SAxel Dörfler = media_request_info::B_REQUEST_FORMAT_CHANGE; 304dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 305*b289aaf6SAxel Dörfler replycommand.info.status = status; 306dfb2ad61Sbeveloper //replycommand.info.cookie 307dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 308dfb2ad61Sbeveloper replycommand.info.source = command->source; 309dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 310*b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 311*b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 31252a38012Sejakowatz return B_OK; 31352a38012Sejakowatz } 31452a38012Sejakowatz 31552a38012Sejakowatz case PRODUCER_VIDEO_CLIPPING_CHANGED: 31652a38012Sejakowatz { 317*b289aaf6SAxel Dörfler const producer_video_clipping_changed_command* command 318*b289aaf6SAxel Dörfler = static_cast< 319*b289aaf6SAxel Dörfler const producer_video_clipping_changed_command*>(data); 320dfb2ad61Sbeveloper node_request_completed_command replycommand; 321*b289aaf6SAxel Dörfler status_t status = VideoClippingChanged(command->source, 322*b289aaf6SAxel Dörfler command->short_count, (int16 *)command->shorts, 323*b289aaf6SAxel Dörfler command->display, NULL); 324dfb2ad61Sbeveloper if (command->destination == media_destination::null) 32552a38012Sejakowatz return B_OK; 326*b289aaf6SAxel Dörfler replycommand.info.what 327*b289aaf6SAxel Dörfler = media_request_info::B_SET_VIDEO_CLIPPING_FOR; 328dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 329*b289aaf6SAxel Dörfler replycommand.info.status = status; 330dfb2ad61Sbeveloper //replycommand.info.cookie 331dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 332dfb2ad61Sbeveloper replycommand.info.source = command->source; 333dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 334dfb2ad61Sbeveloper replycommand.info.format.type = B_MEDIA_RAW_VIDEO; 335dfb2ad61Sbeveloper replycommand.info.format.u.raw_video.display = command->display; 336*b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 337*b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 33852a38012Sejakowatz return B_OK; 33952a38012Sejakowatz } 34052a38012Sejakowatz 34152a38012Sejakowatz case PRODUCER_ADDITIONAL_BUFFER_REQUESTED: 34252a38012Sejakowatz { 343*b289aaf6SAxel Dörfler const producer_additional_buffer_requested_command* command 344*b289aaf6SAxel Dörfler = static_cast< 345*b289aaf6SAxel Dörfler const producer_additional_buffer_requested_command*>(data); 346*b289aaf6SAxel Dörfler AdditionalBufferRequested(command->source, command->prev_buffer, 347*b289aaf6SAxel Dörfler command->prev_time, command->has_seek_tag 348*b289aaf6SAxel Dörfler ? &command->prev_tag : NULL); 34952a38012Sejakowatz return B_OK; 35052a38012Sejakowatz } 35152a38012Sejakowatz 35252a38012Sejakowatz case PRODUCER_LATENCY_CHANGED: 35352a38012Sejakowatz { 354*b289aaf6SAxel Dörfler const producer_latency_changed_command* command 355*b289aaf6SAxel Dörfler = static_cast<const producer_latency_changed_command*>(data); 356*b289aaf6SAxel Dörfler LatencyChanged(command->source, command->destination, 357*b289aaf6SAxel Dörfler command->latency, command->flags); 35852a38012Sejakowatz return B_OK; 35952a38012Sejakowatz } 36052a38012Sejakowatz 36152a38012Sejakowatz case PRODUCER_LATE_NOTICE_RECEIVED: 36252a38012Sejakowatz { 363*b289aaf6SAxel Dörfler const producer_late_notice_received_command* command 364*b289aaf6SAxel Dörfler = static_cast< 365*b289aaf6SAxel Dörfler const producer_late_notice_received_command*>(data); 366*b289aaf6SAxel Dörfler LateNoticeReceived(command->source, command->how_much, 367*b289aaf6SAxel Dörfler command->performance_time); 36852a38012Sejakowatz return B_OK; 36952a38012Sejakowatz } 37052a38012Sejakowatz 37152a38012Sejakowatz case PRODUCER_ENABLE_OUTPUT: 37252a38012Sejakowatz { 373*b289aaf6SAxel Dörfler const producer_enable_output_command* command 374*b289aaf6SAxel Dörfler = static_cast<const producer_enable_output_command*>(data); 375dfb2ad61Sbeveloper node_request_completed_command replycommand; 376dfb2ad61Sbeveloper EnableOutput(command->source, command->enabled, NULL); 377dfb2ad61Sbeveloper if (command->destination == media_destination::null) 37852a38012Sejakowatz return B_OK; 379*b289aaf6SAxel Dörfler 380dfb2ad61Sbeveloper replycommand.info.what = media_request_info::B_SET_OUTPUT_ENABLED; 381dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 382dfb2ad61Sbeveloper replycommand.info.status = B_OK; 383dfb2ad61Sbeveloper //replycommand.info.cookie 384dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 385dfb2ad61Sbeveloper replycommand.info.source = command->source; 386dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 387dfb2ad61Sbeveloper //replycommand.info.format 388*b289aaf6SAxel Dörfler SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, 389*b289aaf6SAxel Dörfler &replycommand, sizeof(replycommand)); 39052a38012Sejakowatz return B_OK; 39152a38012Sejakowatz } 392*b289aaf6SAxel Dörfler } 39352a38012Sejakowatz 39452a38012Sejakowatz return B_ERROR; 39552a38012Sejakowatz } 39652a38012Sejakowatz 39752a38012Sejakowatz 39852a38012Sejakowatz void 39952a38012Sejakowatz BBufferProducer::AdditionalBufferRequested(const media_source& source, 400*b289aaf6SAxel Dörfler media_buffer_id previousBuffer, bigtime_t previousTime, 401*b289aaf6SAxel Dörfler const media_seek_tag* previousTag) 40252a38012Sejakowatz { 40352a38012Sejakowatz CALLED(); 40452a38012Sejakowatz // may be implemented by derived classes 40552a38012Sejakowatz } 40652a38012Sejakowatz 40752a38012Sejakowatz 40852a38012Sejakowatz void 40952a38012Sejakowatz BBufferProducer::LatencyChanged(const media_source& source, 410*b289aaf6SAxel Dörfler const media_destination& destination, bigtime_t newLatency, uint32 flags) 41152a38012Sejakowatz { 41252a38012Sejakowatz CALLED(); 41352a38012Sejakowatz // may be implemented by derived classes 41452a38012Sejakowatz } 41552a38012Sejakowatz 41652a38012Sejakowatz 41752a38012Sejakowatz status_t 418*b289aaf6SAxel Dörfler BBufferProducer::SendBuffer(BBuffer* buffer, const media_source& source, 41952a38012Sejakowatz const media_destination& destination) 42052a38012Sejakowatz { 42152a38012Sejakowatz CALLED(); 42252a38012Sejakowatz if (destination == media_destination::null) 42352a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 424*b289aaf6SAxel Dörfler if (source == media_source::null) 425*b289aaf6SAxel Dörfler return B_MEDIA_BAD_SOURCE; 42652a38012Sejakowatz if (buffer == NULL) 42752a38012Sejakowatz return B_BAD_VALUE; 42852a38012Sejakowatz 429dfb2ad61Sbeveloper consumer_buffer_received_command command; 430dfb2ad61Sbeveloper command.buffer = buffer->ID(); 431*b289aaf6SAxel Dörfler command.header = *buffer->Header(); 432*b289aaf6SAxel Dörfler command.header.buffer = command.buffer; 433*b289aaf6SAxel Dörfler command.header.source_port = source.port; 434*b289aaf6SAxel Dörfler command.header.source = source.id; 435dfb2ad61Sbeveloper command.header.destination = destination.id; 4361df08d39Sbeveloper command.header.owner = 0; // XXX fill with "buffer owner info area" 437*b289aaf6SAxel Dörfler command.header.start_time += fDelay; 438*b289aaf6SAxel Dörfler // time compensation as set by BMediaRoster::SetProducerRunModeDelay() 43952a38012Sejakowatz 440a6d316d8Sbeveloper //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); 441a6d316d8Sbeveloper 442*b289aaf6SAxel Dörfler return SendToPort(destination.port, CONSUMER_BUFFER_RECEIVED, &command, 443*b289aaf6SAxel Dörfler sizeof(command)); 44452a38012Sejakowatz } 44552a38012Sejakowatz 44652a38012Sejakowatz 44752a38012Sejakowatz status_t 44852a38012Sejakowatz BBufferProducer::SendDataStatus(int32 status, 449*b289aaf6SAxel Dörfler const media_destination& destination, bigtime_t atTime) 45052a38012Sejakowatz { 45152a38012Sejakowatz CALLED(); 45240f36b03Sbeveloper if (IS_INVALID_DESTINATION(destination)) 45352a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 45452a38012Sejakowatz 455dfb2ad61Sbeveloper consumer_producer_data_status_command command; 456dfb2ad61Sbeveloper command.for_whom = destination; 457dfb2ad61Sbeveloper command.status = status; 458*b289aaf6SAxel Dörfler command.at_performance_time = atTime; 45952a38012Sejakowatz 460*b289aaf6SAxel Dörfler return SendToPort(destination.port, CONSUMER_PRODUCER_DATA_STATUS, &command, 461*b289aaf6SAxel Dörfler sizeof(command)); 46252a38012Sejakowatz } 46352a38012Sejakowatz 46452a38012Sejakowatz 46552a38012Sejakowatz status_t 46652a38012Sejakowatz BBufferProducer::ProposeFormatChange(media_format* format, 467*b289aaf6SAxel Dörfler const media_destination& destination) 46852a38012Sejakowatz { 46952a38012Sejakowatz CALLED(); 470*b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 47152a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 47252a38012Sejakowatz 4738c6a6096Sbeveloper consumer_accept_format_request request; 4748c6a6096Sbeveloper consumer_accept_format_reply reply; 47552a38012Sejakowatz 476*b289aaf6SAxel Dörfler request.dest = destination; 4778c6a6096Sbeveloper request.format = *format; 478*b289aaf6SAxel Dörfler status_t status = QueryPort(destination.port, CONSUMER_ACCEPT_FORMAT, 479*b289aaf6SAxel Dörfler &request, sizeof(request), &reply, sizeof(reply)); 480*b289aaf6SAxel Dörfler if (status != B_OK) 481*b289aaf6SAxel Dörfler return status; 48252a38012Sejakowatz 48352a38012Sejakowatz *format = reply.format; 4848c6a6096Sbeveloper return B_OK; 48552a38012Sejakowatz } 48652a38012Sejakowatz 48752a38012Sejakowatz 48852a38012Sejakowatz status_t 489*b289aaf6SAxel Dörfler BBufferProducer::ChangeFormat(const media_source& source, 490*b289aaf6SAxel Dörfler const media_destination& destination, media_format* format) 49152a38012Sejakowatz { 49252a38012Sejakowatz CALLED(); 493*b289aaf6SAxel Dörfler if (IS_INVALID_SOURCE(source)) 49452a38012Sejakowatz return B_MEDIA_BAD_SOURCE; 495*b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 49652a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 49752a38012Sejakowatz 498dfb2ad61Sbeveloper consumer_format_changed_request request; 499dfb2ad61Sbeveloper consumer_format_changed_reply reply; 50052a38012Sejakowatz 501*b289aaf6SAxel Dörfler request.producer = source; 502*b289aaf6SAxel Dörfler request.consumer = destination; 5038c6a6096Sbeveloper request.format = *format; 50452a38012Sejakowatz 505dfb2ad61Sbeveloper // we use a request/reply to make this synchronous 506*b289aaf6SAxel Dörfler return QueryPort(destination.port, CONSUMER_FORMAT_CHANGED, &request, 507*b289aaf6SAxel Dörfler sizeof(request), &reply, sizeof(reply)); 50852a38012Sejakowatz } 50952a38012Sejakowatz 51052a38012Sejakowatz 51152a38012Sejakowatz status_t 512*b289aaf6SAxel Dörfler BBufferProducer::FindLatencyFor(const media_destination& destination, 513*b289aaf6SAxel Dörfler bigtime_t* _latency, media_node_id* _timesource) 51452a38012Sejakowatz { 51552a38012Sejakowatz CALLED(); 516*b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 51752a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 51852a38012Sejakowatz 519dfb2ad61Sbeveloper consumer_get_latency_for_request request; 520dfb2ad61Sbeveloper consumer_get_latency_for_reply reply; 52152a38012Sejakowatz 522*b289aaf6SAxel Dörfler request.for_whom = destination; 52352a38012Sejakowatz 524*b289aaf6SAxel Dörfler status_t status = QueryPort(destination.port, CONSUMER_GET_LATENCY_FOR, 525*b289aaf6SAxel Dörfler &request, sizeof(request), &reply, sizeof(reply)); 526*b289aaf6SAxel Dörfler if (status != B_OK) 527*b289aaf6SAxel Dörfler return status; 52852a38012Sejakowatz 529*b289aaf6SAxel Dörfler *_latency = reply.latency; 530*b289aaf6SAxel Dörfler *_timesource = reply.timesource; 531*b289aaf6SAxel Dörfler return B_OK; 53252a38012Sejakowatz } 53352a38012Sejakowatz 53452a38012Sejakowatz 53552a38012Sejakowatz status_t 536*b289aaf6SAxel Dörfler BBufferProducer::FindSeekTag(const media_destination& destination, 537*b289aaf6SAxel Dörfler bigtime_t targetTime, media_seek_tag* _tag, bigtime_t* _tagged_time, 538*b289aaf6SAxel Dörfler uint32* _flags, uint32 flags) 53952a38012Sejakowatz { 54052a38012Sejakowatz CALLED(); 541*b289aaf6SAxel Dörfler if (IS_INVALID_DESTINATION(destination)) 54252a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 54352a38012Sejakowatz 544dfb2ad61Sbeveloper consumer_seek_tag_requested_request request; 545dfb2ad61Sbeveloper consumer_seek_tag_requested_reply reply; 54652a38012Sejakowatz 547*b289aaf6SAxel Dörfler request.destination = destination; 548*b289aaf6SAxel Dörfler request.target_time = targetTime; 549*b289aaf6SAxel Dörfler request.flags = flags; 55052a38012Sejakowatz 551*b289aaf6SAxel Dörfler status_t status = QueryPort(destination.port, CONSUMER_SEEK_TAG_REQUESTED, 552*b289aaf6SAxel Dörfler &request, sizeof(request), &reply, sizeof(reply)); 553*b289aaf6SAxel Dörfler if (status != B_OK) 554*b289aaf6SAxel Dörfler return status; 55552a38012Sejakowatz 556*b289aaf6SAxel Dörfler *_tag = reply.seek_tag; 557*b289aaf6SAxel Dörfler *_tagged_time = reply.tagged_time; 558*b289aaf6SAxel Dörfler *_flags = reply.flags; 559*b289aaf6SAxel Dörfler return B_OK; 56052a38012Sejakowatz } 56152a38012Sejakowatz 56252a38012Sejakowatz 56352a38012Sejakowatz void 564*b289aaf6SAxel Dörfler BBufferProducer::SetInitialLatency(bigtime_t initialLatency, uint32 flags) 56552a38012Sejakowatz { 566*b289aaf6SAxel Dörfler fInitialLatency = initialLatency; 56752a38012Sejakowatz fInitialFlags = flags; 56852a38012Sejakowatz } 56952a38012Sejakowatz 570*b289aaf6SAxel Dörfler 571*b289aaf6SAxel Dörfler // #pragma mark - private BBufferProducer 572*b289aaf6SAxel Dörfler 57352a38012Sejakowatz 57452a38012Sejakowatz /* 57552a38012Sejakowatz private unimplemented 57652a38012Sejakowatz BBufferProducer::BBufferProducer() 57752a38012Sejakowatz BBufferProducer::BBufferProducer(const BBufferProducer &clone) 57852a38012Sejakowatz BBufferProducer & BBufferProducer::operator=(const BBufferProducer &clone) 57952a38012Sejakowatz */ 58052a38012Sejakowatz 58152a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_0(void*) { return B_ERROR; } 58252a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_1(void*) { return B_ERROR; } 58352a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_2(void*) { return B_ERROR; } 58452a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_3(void*) { return B_ERROR; } 58552a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_4(void*) { return B_ERROR; } 58652a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_5(void*) { return B_ERROR; } 58752a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_6(void*) { return B_ERROR; } 58852a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_7(void*) { return B_ERROR; } 58952a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_8(void*) { return B_ERROR; } 59052a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_9(void*) { return B_ERROR; } 59152a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_10(void*) { return B_ERROR; } 59252a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_11(void*) { return B_ERROR; } 59352a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_12(void*) { return B_ERROR; } 59452a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_13(void*) { return B_ERROR; } 59552a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_14(void*) { return B_ERROR; } 59652a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_15(void*) { return B_ERROR; } 59752a38012Sejakowatz 59852a38012Sejakowatz 599*b289aaf6SAxel Dörfler //! Deprecated. 60052a38012Sejakowatz status_t 601*b289aaf6SAxel Dörfler BBufferProducer::SendBuffer(BBuffer* buffer, 602*b289aaf6SAxel Dörfler const media_destination& destination) 603*b289aaf6SAxel Dörfler { 604*b289aaf6SAxel Dörfler CALLED(); 605*b289aaf6SAxel Dörfler 606*b289aaf6SAxel Dörfler // Try to find the source - this is the best we can do 607*b289aaf6SAxel Dörfler media_output output; 608*b289aaf6SAxel Dörfler int32 cookie = 0; 609*b289aaf6SAxel Dörfler status_t status = GetNextOutput(&cookie, &output); 610*b289aaf6SAxel Dörfler if (status != B_OK) 611*b289aaf6SAxel Dörfler return status; 612*b289aaf6SAxel Dörfler 613*b289aaf6SAxel Dörfler return SendBuffer(buffer, output.source, destination); 614*b289aaf6SAxel Dörfler } 615*b289aaf6SAxel Dörfler 616*b289aaf6SAxel Dörfler 617*b289aaf6SAxel Dörfler status_t 618*b289aaf6SAxel Dörfler BBufferProducer::clip_shorts_to_region(const int16* data, int count, 61952a38012Sejakowatz BRegion* output) 62052a38012Sejakowatz { 62152a38012Sejakowatz UNIMPLEMENTED(); 62252a38012Sejakowatz return B_ERROR; 62352a38012Sejakowatz } 62452a38012Sejakowatz 62552a38012Sejakowatz 62652a38012Sejakowatz status_t 627*b289aaf6SAxel Dörfler BBufferProducer::clip_region_to_shorts(const BRegion* input, int16* data, 628*b289aaf6SAxel Dörfler int maxCount, int* _count) 62952a38012Sejakowatz { 63052a38012Sejakowatz UNIMPLEMENTED(); 63152a38012Sejakowatz return B_ERROR; 63252a38012Sejakowatz } 633